多线程知识点 自定义Operation

来源:互联网 发布:刀哥swift3.0源码 编辑:程序博客网 时间:2024/05/16 15:30

标题


自定义Operation

在ViewController.m里面 导入DownLoadOperation 这个类

#import "ViewController.h"

#import "DownLoadOperation.h"


// 代理传值:导入代理

@interface ViewController ()<DownLoadOperationDelegate>

{

  定义一个全局变量

    UIImageView *imageView;


}

@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    

//    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveNot:) name:@"下载完成" object:nil];

    

    

    

    

    imageView = [[UIImageView alloc]initWithFrame:self.view.frame];

    

     [self.view addSubview:imageView];

    

    DownLoadOperation * downLoad = [[DownLoadOperation alloc]initWithDownLoadMessageURL:@"http://file.bmob.cn/M01/37/F1/oYYBAFXdo8yANhgHAABx04fZA8s908.png"];

    

//   5. 代理传值:挂上代理

    downLoad.delegate = self;

//    如果调用Block的时候 还没有找到Block就会崩溃(OC里面调用方法一样  如果调用的方法没有去写也会崩溃)

//    downLoad.bringImageBlock = ^(UIImage *image){

//        

//        

//        imageView.image = image;

//        

//    };

    

//    [downLoad start];

    

//    异步加载图片

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    

    queue.maxConcurrentOperationCount = 1;

    

    [queue addOperation:downLoad];

    

    

}


//   通知传值

//- (void)receiveNot:(NSNotification *)sender

//{

//    

//NSLog(@"%@",sender.object);

//    imageView.image = sender.object;

//

//}



//  6.代理传值:实现代理方法

- (void)didFinshDownLoadWithImage:(UIImage *)image

{


    imageView.image = image;



}




- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end


在DownLoadOperation.h 里面导入UIKit/UIKit.h框架

#import <Foundation/Foundation.h>

#import <UIKit/UIKit.h>


//  1.声明一个代理方法

@protocol DownLoadOperationDelegate <NSObject>



- (void)didFinshDownLoadWithImage:(UIImage *)image;




@end


@interface DownLoadOperation : NSOperation

{

    

//  声明一个全局变量

    NSString *urlString;

}


//nonatomic 在多线程里面 使用nonatomic 不能保证 在多线程 里面数据传递的安全

//@property(atomic,retain)UIImage *imageContent;


// @property(atomic,copy)void(^bringImageBlock)(UIImage *image);


//  写一个下载图片的operation需要URL

- (instancetype)initWithDownLoadMessageURL:(NSString *)url;



// 2. 声明属性作为代理的接口

@property(assign)id<DownLoadOperationDelegate>delegate;


@end


在 DownLoadOperation.m里面


- (instancetype)initWithDownLoadMessageURL:(NSString *)url

{


    self = [super init];

    if (self) {

        

        urlString = url;

        

    }


    return self;

}



//Operation 具体操作写在main里面 start的时候会执行里面的操作

- (void)main

{



    NSLog(@"自定义完了Operation方法");

//     具体下载的操作

    NSURL *url = [NSURL URLWithString:urlString];

    

//    不管同步还是异步此方法都要有

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

  NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    

    UIImage *image = [UIImage imageWithData:data];

    

    

    NSLog(@"%@",image);

    


//    使用Block传值

//    self.bringImageBlock(image);

    

//    使用通知传值

    

    

//    [[NSNotificationCenter defaultCenter]postNotificationName:@"下载完成" object:image];

    

//   3.代理传值:调用代理方法

    

    [self.delegate didFinshDownLoadWithImage:image];

    

    

    

}

                                   线程部分


1.当用户下载资源、进行图像处理、耗时数据处理等任务 往往希望操作这个任务的时候 其他的操作不会被中断 这时候 就用到了 多线程


2.在单线程中一个线程只能执行一个任务,一个任务处理不完 另一个任务就不能开始 这样会影响用户体验 让用户感觉 APP卡顿

每个应用程序的内部,存在一个或多个执行线程,它同时 或 在一个几乎同时执行不同的操作



面试题: 什么是进程? 什么是线程?什么是多线程

进程与线程:每个系统运行的程序都是一个进程,每个进程里面包含了多个线程

进程: 是指在系统中正在运行的一个应用程序

线程 :是一组指令的集合,程序中一个单个的顺序控制流程,是一个程序中,独立运行的程序片段(一个应用程序里面 单一的顺序控制执行的一个任务)

程序运行后,系统会创建一个叫做(main)主线程的线程,所有的UI控件都必须运行在主线程中,所以也有人叫UI线程

如果将所有的任务都放在主线程中,容易造成阻塞

多线程:在同一应用程序内,同时运行多个线程,完成不同的工作,叫做多线程

为什么要使用多线程:单线程的运用程序中,代码沿直线执行,只有前面的代码执行完了,才会执行后面的代码,中间这段时间,实际上就处于等待状态。当用户执行某项操作,比如上传文件,或则下载文件,主线程会执行这个任务,直到上传结束,主线程才能继续后面的工作,在这段时间内,主线程处于忙碌状态,不会对用户的请求作出任何回应,


ios中有多线程方式

ios中有三种多线程策略供开发者使用:NSThread, NSOperation(基类不可以直接使用 只能用它的子类) GCD(Grand Central Dispatch)

GCD 苹果推荐的一种 实现 多线程的方式



轻量级: 对系统框架的依赖性程度

NSThread:是这三种策略里面相对轻量级的,需要自己去管理它的生命周期,以及线程之间的同步,线程共享一应用程序的部分内存空间,他们拥有数据相同的访问权限,所以的协调多个线程对同一数据的访问,长做的做法是在访问值之前加锁,

第二部分

NSOperation线程:

  NSOperation 是一个基类 (抽象类)不能直接使用必须使用他的子类他默认时在当前线程进行操作

常与NSOperationQueue 一起使用  在与NSOperationQueue一起使用会自动开辟线程进行操作



GDC:

 Grand Central Dispatch(GCD)是苹果比较提倡的一个多核编程的解决办法

 

 GCD:底层也是用线程来实现的,知识苹果封装了具体操作的方法,这样可以让程序员不用关注实现的细节只需要专注功能的实现

 

 GCD参数:queue:队列 block任务


GCD 有两种执行任务的方式:

 1.同步:dispatch_sync(避免在主队列中使用同步执行主线程任务容易死锁)

 

 2.异步: dispatch_async

 

 

 同步和异步的区别:

 

 (1)同步:当前线程中执行

 (2)异步:在另一条线程中执行



GCD执行多个任务的<队列>方式 也有两种:


1.串行队列:让一个任务接着一个地执行(一个任务执行完毕后,在执行下一个任务)


2.并发队列:可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效



串行队列有分为两种:

dispatch_get_main_queue()  主队列 串行队列         dispatch_queue_create("", NULL)串行队列 

1.主队列   dispatch_get_main_queue( )主队列是GCD自带的一种特殊的串行队列


2.创建一个队列dispatch_queue_creat



并发队列:GCD

/*并发队列: 可以指定队列任务的优先级

 使用全局并发队列

#define DISPATCH_QUEUE_PRIORITY_HIGH 2 //

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认(中)

#define DISPATCH_QUEUE_PRIORITY_LOW (-2) //

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台

  

   GCD默认已经提供了全局的病发队列,供整个应用使用不需要手动创建  dispatch_get_global_queue

    

 long identifier 指定优先级

*/


    dispatch_queue_t firstQueue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0);

    

    

    dispatch_queue_t secondQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

    

    dispatch_queue_t  thirdQueue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);


    dispatch_async(firstQueue, ^{

         

         NSLog(@"11111");

     });

    

    dispatch_async(secondQueue, ^{

        

        NSLog(@"22222");

    });


    dispatch_async(thirdQueue, ^{

        

        NSLog(@"33333");

    });


   

}


0 0