多线程之NSOperation


NSOperation

NSOperation/NSOperationQueue 配合使用费,开启线程! OC的框

基于 GCD ! 更加面向对象(oc),但GCD效率更高!

NSOperation : 封装了 GCD 中的"任务"!

NSOperationQueue : 封装了 GCD 中的"队列"!



NSOperation的作用
配合使用NSOperationNSOperationQueue也能实现多线程编程

NSOperationNSOperationQueue实现多线程的具体步骤
1>先将需要执行的操作封装到一个NSOperation对象中
2>然后将NSOperation对象添加到NSOperationQueue
3>系统会自动将NSOperationQueue中的NSOperation取出来,将取出的NSOperation封装的操作放到一条新线程中执行

NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类

使用NSOperation子类的方式有3
1>NSInvocationOperation
2>NSBlockOperation
3> 自定义子类继承NSOperation,实现内部相应的方法


NSInvocationOperation
示例:

    // 1.实例化操作对象

    NSInvocationOperation *op1 = [[NSInvocationOperationalloc] initWithTarget:selfselector:@selector(test1)object:nil];

    

    NSInvocationOperation *op2 = [[NSInvocationOperationalloc] initWithTarget:selfselector:@selector(test2)object:nil];


    NSInvocationOperation *op3 = [[NSInvocationOperationalloc] initWithTarget:selfselector:@selector(test3)object:nil];


    // 2. 创建队列

  

    NSOperationQueue *queue = [[NSOperationQueuealloc] init]; 

    

   // 3. 将操作添加到非主队列中

    [queue addOperation:op1];

    [queue addOperation:op2];

    [queue addOperation:op3];


    // NSOperation执行方式2: 直接启动!直接在当前线程执行!

    [op1 start];

    [op2 start];

    [op3 start];


NSBlockOperation

示例:

    // 1.实例化 NSOperation子类对象

    NSBlockOperation *op4 = [NSBlockOperationblockOperationWithBlock:^{

        //

        NSLog(@"耗时操作2------------");

    }];

 

    // NSOperationQueue 

    // 2.创建队列

    NSOperationQueue *queue = [[NSOperationQueuealloc] init];

    

    // NSOperation使用:将操作添加到队列中!

    [queue addOperation:op4];


通过addExecutionBlock:方法添加更多的操作

- (void)addExecutionBlock:(void (^)(void))block;

注意:只要NSBlockOperation封装的操作数>1,就会异步执行操作


NSOperationQueue 的作用
NSOperation 可以调用 start 方法来执行任务, 但默认是同步执行
如果 NSOperation 添加到 NSOperationQueue 操作队列 中, 系统会自动 异步执行 NSOperation 中的操作

添加操作到 NSOperationQueue

- (void)addOperation:(NSOperation*)op;

- (void)addOperationWithBlock:(void (^)(void))block;


最大并发数:同时执行的任务数

- (NSInteger)maxConcurrentOperationCount;

- (void)setMaxConcurrentOperationCount:(NSInteger)cat;


队列的取消、暂停、恢复

取消队列的所有操作

- (void)cancelAllOperations;

提示:也可以调用NSOperation- (void)cancel方法取消单个操作

 暂停和恢复队列

- (void)setSuspended:(BOOL)b;//YES代表暂停队列,NO代表恢复队列

- (BOOL)isSuspended;


操作依赖

       添加操作依赖的注意点:

    // 1.不要添加循环依赖!以下这种写法是错误

    [op2 addDependency:op1];

    [op1 addDependency:op2];


   // 2. 一定要在将操作添加到操作队列中之前添加操作依赖!

   // 优点:对于不同操作队列中的操作,操作依赖依然有效!

    // 添加操作依赖!

    [op2 addDependency:op1];

    [op3 addDependency:op2];

    [op4 addDependency:op3];


自定义子类继承NSOperation
自定义 NSOperation 的步骤很简单
重写- ( void)main 方法,在里面实现想执行的任务

注意点
自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释放池)
经常通过- ( BOOL)isCancelled 方法检测操作是否被取消,对取消做出响应
示例代码

@implementation WTDownloadOperation

// 重写 NSOperation main 方法!

// 当把自定义的操作添加到操作队列中,或者直接调用操作的  start 方法之后,都会自动来执行 main方法中的内容!

-(void)main

{

    // 为了能够及时释放内存,一般会手动书写一个 autoreleasepool!苹果官方文档不要求写!

    @autoreleasepool {

        UIImage *image = [selfdownloadWebImageWithUrlString:@"图片地址"];

        // 回到主线程

        dispatch_async(dispatch_get_main_queue(), ^{

            

            // 显示图片

            self.imageView.image = image;

            

        });

    }

}


// 下载网络图片的方法

- (UIImage *)downloadWebImageWithUrlString:(NSString *)urlString

{

    NSURL *url = [NSURLURLWithString:urlString];

    

    // 下载方法!耗时方法!

    NSData *data = [NSDatadataWithContentsOfURL:url];

    

    UIImage *image = [UIImageimageWithData:data];

    

    return image;

}

@end





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值