多线程3-NSOperation

来源:互联网 发布:顽固木马清除软件 编辑:程序博客网 时间:2024/06/05 19:35

NSOperation

1. 简介

OC语言基于CGD的面向对象装.提供了一些GCD不好实现的功能,苹果推荐使用;同样比比关系线程和生命周期.

NSOperation是一个抽象类,不能直接使用(方法没有实现),是用来约束子类都具有共同的属性和方法.
主要使用NSOperation的子类:

  • NSInvocationOperation
  • NSBlockOperation
  • 自定义Operation

2. 简单使用

步骤:

  1. 将需要执行的操作封装到NSOperation对象对象中.
  2. 将对象添加到NSOperationQueue队列中;(不同类型对象加到同一个队列中)

之后系统会自动将NSOperation取出,放到一条新线程中;

2.1 NSInvocationOperation 的使用

  • 调用NSInvocationOperation 的 initWithTarget: selector: object:方法来创建此对象;
  • 调用对象方法 start来调用;
  • 注意:默认情况下,调用start方法后并不会开启一条新线程去执行操作,只有将NSOperation操作放到一个NSOperationqueue中,才会异步执行操作;

例:

//1.创建操作NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];//start方法更新操作的状态   调用main方法//[op start];  //不开启新线程,一般是不会这么操作的;//2.创建队列NSOperationQueue *queue = [NSOperation alloc] init];//3.把操作添加到队列[queue addOperation:op];    //这样才能异步执行;

2.2 NSBlockOperation 的使用—常用!

使用步骤同上,只是操作直接写在block块内;

NSOperationQueue *queue = [[NSOperationQueue alloc] init];NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{    NSLog(@"%@", [NSThread currentThread]);}];[queue addOperation:op];//可以直接添加block块,  省去第二步创建操作对象;[queue addOperationWithBlock:^{    NSLog(@"%@", [NSThread currentThread]);}];    // 简易模式.[NSOperationQueue new] addOperationWithBlock:^{    NSLog(@"%@", [NSThread currentThread]);}];

线程通信如果子线程中需要更新UI控件的,调用 转到主线程执行操作

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {     }];即可

线程同步监听操作完成,

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{    [NSThread sleepForTimeInterval:2];    NSLog(@"hello %@",[NSThread currentThread]);}];//hello打印操作完成之后才会执行end打印[op setCompletionBlock:^{    NSLog(@"end %@",[NSThread currentThread]);}];[self.queue addOperation:op];

2.3 自定义Operation

3. NSOperation的高级功能

介绍之前先简单对比下GCD的区别:

  • GCD是将任务(block)添加到队列(串行/并行/全局/主队列),并且以同步/异步的方式执行任务的函数
  • 附加功能:
    • 一次性执行
    • 延迟执行
    • 调度组

  • NSOperation将操作(异步的任务)添加到队列(并发队列),就会执行指定操作的函数
  • 附加功能:
    • 最大并发数
    • 队列的暂停与继续
    • 取消队列操作
    • 可以直接指定操作件的依赖关系

3.1 最大并发数

设置队列 queue 同时执行的任务数,可以间接的控制子线程的创建数量;
queue点语法或值setMaxConcurrentOperationCount: 来设置

queue.OperationCount获取队列中操作数

3.2 队列暂停与取消操作

取消和暂停操作不会对正在执行的操作有影响;

暂停: 点语法和set方法设置suspended.

self.queue.suspended = YES;  //暂停   要继续赋值NO即可;

取消:

//取消所有操作.清空队列.[self.queue cancelAllOperations];//取消当个操作[operation cancel];//不需要写额外代码 比GCD和NSThread要省心

另外:
同NSThread一样有操作优先级设置,iOS8之后叫服务质量qualityOfService;操作优先级高,只是表示操作被优先执行的几率高,并不是说优先级高的操作先执行,优先级低的操作后执行;
点语法和set方法设置qualityOfService;值是枚举类型,依次从高到低;

  1. 用户交互: NSQualityOfServiceUserInteractive = 0x21
  2. 用户主动发起: NSQualityOfServiceUserInitiated = 0x19
  3. 实用工具: NSQualityOfServiceUtility = 0x11
  4. 后台: NSQualityOfServiceBackground = 0x09
  5. 默认: NSQualityOfServiceDefault = -1

3.3 解决线程同步,操作依赖

NSOperation直接可以直接设置依赖关系,来保证线程同步;(可以再不同的队列中操作直接创建依赖关系)

[operationB addDependency:operationA]; // 操作B依赖于操作A
注意: 不要循环依赖–死锁;

0 0