多线程 NSOperation

苹果文档:
删除指定的依赖关系

 NSOperation 是另一个”并发技术”,程序员不需要关心,,并发技术 不是多线程

NSOperation 
     - 核心概念:把操作(异步)添加到队列(全局的并发队列)!
     - 主队列 mainQueue
     - OC的框架 更加面向对象
     - 是对 GCD 的封装
     - iOS 2.0 推出的,苹果在推出GCD之后,对NSOperation的底成全部重写了.
     - 高级功能:
        - 最大操作并发数(GCD不好做)
        -在iOS 7.0 之前 使用GCD & NSOperation 能够开启的线程不多,5-6条
        - 从iOS 8.0 开始,能够开很多个线程,如果不控制,会造成资源浪费
       - 继续/暂停/全部取消
       - 依赖关系(CGD,同步认为是来制定依赖关系!)

GCD:
      - 将”任务(block)”添加到队列(串行/并发/主队列),并且指定执行的函数(同步/异步)
      - C 语言的框架 dispatch_xxx 函数
      - iOS 4.0 推出的,针对多核处理器的并发技术
      - iOS 4.0 推出的,针对多核处理器的并发技术
      -高级功能:
           -  一次性 once
           - 延迟操作 after
          - 调度组 (op可以做,但是太复杂) 

 The NSOperation class is an abstract class you use to encapsulate the code and data associated with a single task.
 - NSOperation
类是一个"抽象类",封装与一个任务关联的代码和数据
 - 抽象类不能直接使用,需要使用子类

NSOperation 

 子类:
  * NSBlockOperation (块)
  * NSInvocationOperation(调度.用得少)

- 队列 NSOperationQueue

目前学过的抽象类
1. UIGestureRecognizer
 2. CAAnimation
 3. CAPropertyAnimation
(属性动画)
    - CABasicAnimation
(基本动画,fromValue, toValue
    - CAKeyframeAnimation
valuespath
    - 通过修改图层的可动画属性


// MARK: - NSBlockOperation
// block operation 将代码都写在一起,便于维护



// MARK: - 更简单的
// 只要是 NSOpeartion 的子类,都可以直接添加到队列!
// MARK: 线程间通讯
- (
void)opDemo5 {
   
    [
self.queue addOperationWithBlock:^{
       
NSLog(@"耗时的操作 %@", [NSThread currentThread]);
      
       
// 在主线程更新 UI
        [[
NSOperationQueue mainQueue] addOperationWithBlock:^{
           
NSLog(@"更新 UI %@", [NSThread currentThread]);
        }];
    }];
}
- (void)opDemo4 {
   
// 通常在应用程序中,会用一个属性来记录 队列,全局管理所有的异步操作
//    NSOperationQueue *q = [[NSOperationQueue alloc] init];
   
   
// 直接向队列添加 block 操作
   
for (int i = 0; i < 10; ++i) {
        [
self.queue addOperationWithBlock:^{
           
NSLog(@"%@ - %d", [NSThread currentThread], i);
        }];
    }
   
   
// 向队列添加 NSBlockOperation
   
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
       
NSLog(@"BLOCK --- %@ - %d", [NSThread currentThread], 100);
    }];
    [
self.queue addOperation:op1];
   
   
// invocation op
   
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"invocation"];
   
    [
self.queue addOperation:op2];
}


- (void)opDemo3 {
   
NSOperationQueue *q = [[NSOperationQueue alloc] init];
   
   
for (int i = 0; i < 10; ++i) {
       
// 操作
       
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
           
NSLog(@"%@ - %d", [NSThread currentThread], i);
        }];
       
       
// 将操作添加到队列
        [q
addOperation:op];
    }
}


 NSOpeartion 是对 GCD 的封装,是 OC 的!比 GCD 的使用简单
 
 
队列:全局队列(并发队列)
 
操作:异步执行的任务
 */

- (
void)opDemo2 {
   
NSOperationQueue *q = [[NSOperationQueue alloc] init];
   
   
for (int i = 0; i < 10; ++i) {
       
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@(i)];
       
        [q
addOperation:op];
    }
}





- (void)opDemo1 {
   
// Invocation: 调度,调用
   
// 提示:NSInvocation 是一个非常古老的技术,暂时不建议大家学习和探索!
   
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];
   
   
// 启动操作,会在当前线程执行 @selector 方法
//    [op start];
   
// 将操作添加到队列 -> 异步执行 @selector 方法
   
NSOperationQueue *q = [[NSOperationQueue alloc] init];
    [q addOperation:op];
 
}
- (void)downloadImage:(id)obj {
   
NSLog(@"%@ - %@", [NSThread currentThread], obj);
}



 七. 最大并发数操作数
- (void)opDemo1 {  
    // 设置队列的最大并发操作数(队列是负责调度任务的)
  self.queue.maxConcurrentOperationCount = 2;
    NSLog(@"start");
    for (int i = 0; i < 20; ++i) {
        [
self.queue addOperationWithBlock:^{
           
// 休眠 效果? 1秒钟之后,全部打印
            [NSThread sleepForTimeInterval:1.0];
            NSLog(@"%@ - %d", [NSThread currentThread], i);
        }];
    }
}


八.暂停/继续
- (IBAction)pauseAndResume {
  
   
// 判断队列中是否有操作,只有包含操作的时候,才继续后续操作
   
if (self.queue.operationCount == 0) {
       
NSLog(@"没有操作");
       
return;
    }
   
   
// 一旦设置了对列的挂起,再继续添加操作,操作都不会执行
   
self.queue.suspended = !self.queue.isSuspended;
   
   
if (self.queue.isSuspended) {
       
// 如果队列被挂起,operationCount 中是包含没有执行完的操作数量
       
NSLog(@"暂停了 %tu", self.queue.operationCount);
    }
else {
       
// 包含队列中所有要调度的操作
       
NSLog(@"继续 %tu", self.queue.operationCount);
    }
}

// MARK: 取消所有操作
// 案例:下载小电影,下载完第一个就后悔了,取消所有下载操作
- (
IBAction)cancelAll {
   
   
// 给队列发送取消操作的消息!
    [
self.queue cancelAllOperations];
   
   
// 直觉上会以为:cancelAllOperations 一调用,队列中就没有操作了!
   
// 结果:cancelAllOperations 方法是通知队列取消其中的操作,在队列取消完成之前,操作计数并不会发生变化!
   
// 包含正在执行中的操作+还没有调度的操作
   
NSLog(@"操作数量:%tu", self.queue.operationCount);
}


依赖关系
// MARK: 依赖关系
// 举个栗子:用户登录,付费,下载,通知用户
- (
void)dependency {

   
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
       
NSLog(@"用户登录 %@", [NSThread currentThread]);
    }];
   
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
       
NSLog(@"付费 %@", [NSThread currentThread]);
    }];
   
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        [
NSThread sleepForTimeInterval:1.0f];
       
NSLog(@"下载 %@", [NSThread currentThread]);
    }];
   
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
       
NSLog(@"更新UI %@", [NSThread currentThread]);
    }];

   
// 注意:在指定依赖关系时,注意不要出现循环依赖
   
// 另外:关于死不死,在不同iOS 版本上不同,不同的 MAC 版本上表现都不一样
   
// 用户登录之前,先更新 UI
    [op1
addDependency:op4];
   
   
// waitUntilFinished == NO,异步的 YES 是同步的
    [
self.queue addOperations:@[op1, op2, op3] waitUntilFinished:NO];
   
   
// 更新UI的操作,应该由主队列来调度
    [[
NSOperationQueue mainQueue] addOperation:op4];
   
    NSLog(@"come here");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值