【iOS进阶】【多线程】2-NSOperation & NSOperationQueue

一、NSOperation & NSOperationQueue

1>简介

  1.NSOperationQueue(操作队列)是由GCD提供的队列模型的Cocoa抽象,是一套Objective-C的API

  2.GCD提供了更加底层的控制,而操作队列则在GCD之上实现了一些方便的功能,这些功能对于开发者而言通常是最好最安全的选择

2>队列及操作

  1.NSOperationQueue有两种不同类型的队列:主队列和自定义队列。主队列运行在主线程上,自定义队列在后台执行

  2.队列处理的任务是NSOperation的子类

   例如:NSInvocationOperation、NSBlockOperation

3>基本使用步骤

  定义操作队列 -> 定义操作 -> 将操作添加到队列

  提示:一旦将操作添加到队列,操作就会立即被调度执行

4>关于性能

  从本质上来看,操作队列的性能会比GCD略低,不过,大多数情况下这点负面影响可以忽略不计,操作队列是并发编程的首选工具

二、操作队列的具体实现

0>在类中声明一个NSOperationQueue成员变量

@interface ViewController ()

@property (nonatomic,strong) NSOperationQueue *myQueue;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.myQueue = [[NSOperationQueue alloc] init];
    
    [self demoOp2];
}

1>NSInvocationOperation(调度操作)

#pragma mark NSInvocationOperation
-(void)demoOp2{
    //定义操作队列
    NSInvocationOperation *op = [[NSInvocationOperation alloc]
                                 initWithTarget:self selector:@selector(testDemoOp2:) object:@"hello"];
    //将操作添加到队列
    [self.myQueue addOperation:op];
    
    //加入到主队列中
    //[[NSOperationQueue mainQueue] addOperation:op];
}
/**
 *  定义操作
 */
-(void)testDemoOp2:(id)obj{
    NSLog(@"%@ - %@",[NSThread currentThread],obj);
}

2>NSBlockOperation(块操作)

#pragma mark NSBlockOperation
-(void)demoOp1
{
    //1.
    NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@",[NSThread currentThread]);
    }];
    //所有的自定义队列,都是在子线程中运行
    [self.myQueue addOperation:block];
    
    
   /**
    * 新建线程是有开销的
    * 设置最大的并发线程数。如果前一个线程工作完成,并销毁,会新建线程。
    * 应用场景:网络开发中,下载工作。(线程开销:CPU、电量、等等)
    * 如果是3G,开3个子线程。如果是WIFI,开6个子线程
    */
    //2.
    //设置最大的并发线程数
    [self.myQueue setMaxConcurrentOperationCount:2];
    for (int i=0;i<10;i++){
        [self.myQueue addOperationWithBlock:^{
            NSLog(@"啊哈哈%@",[NSThread currentThread]);
        }];
    }
    
    //3.
    //在主线程中执行
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        NSLog(@"%@",[NSThread currentThread]);
    }];
}

3>设置操作的依赖关系

#pragma mark 设置任务的执行顺序
-(void)demoOp3{
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"修饰图片%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"保存图片%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"更新UI%@",[NSThread currentThread]);
    }];
    
    //设置执行顺序,Dependency依赖,依赖关系是可以跨队列的。
    //这个属性非常牛逼
    //op2依赖于op1
    [op2 addDependency:op1];
    //op3依赖于op2
    [op3 addDependency:op2];
    //op4依赖于op3
    [op4 addDependency:op3];
    
    //所有的自定义队列,都是在子线程中运行
    [self.myQueue addOperation:op1];
    [self.myQueue addOperation:op2];
    [self.myQueue addOperation:op3];
    //注意!所有的UI的更新需要在主线程上进行
    [[NSOperationQueue mainQueue] addOperation:op4];
    
}

 

posted @ 2015-04-21 20:24  锟斤拷Dy  阅读(141)  评论(0)    收藏  举报