iOS多线程编程篇: Operation 对象 与 Operation Queue

来源:互联网 发布:随机森林优化 编辑:程序博客网 时间:2024/05/17 18:41

概念

Operation Queues 是Cocoa版本的并发dispatch queue,由NSOperationQueue类实现。dispatch queue总是按先进先出的顺序执行任务,而Operation Queues在确定任务执行顺序时,还会考虑其他因素。最主要的一个因素是指定任务是否依赖两一个任务的完成。你在定义任务时配置依赖性,从而创建负责的任务执行顺序图。

Operation objects会产生key-value observing(KVO)通知,对于监控任务的进程非常有用。虽然Operation queue总是并发地执行任务,你可以使用依赖,在需要时确保顺序执行。

Operation

默认的Operation

所有Operation objects都支持以下关键特性
1、支持建立基于图的opration objects依赖。可以阻止某个Operation运行,直到它依赖的所有operation都已经完成。
2、支持可选的completion block,在Operation的主任务完成后调用。
3、支持应用使用KVO通知来监控Operation的执行状态。
4、支持Operation优先级,从而影响相对的执行顺序。
5、支持取消,允许你终止正在执行的任务。

系统默认提供了两个子类化的Operation对象:
NSInvocationOperation:可以直接使用的类,基于应用的一个对象和selector来创建Operation object。如果你已经有现有的方法来执行需要的任务,就可以使用这个类。
NSBlockOperation:可以直接使用的类,用来并发地执行一个或多个blcok对象。Operation object使用“组”的语义来执行多个block对象,所有相关的block都执行完成之后,operation object才算完成。

Operation 任务的执行可通过两个方式:
1、手动调起start
2、将Operation对象添加到一个初始化的Operation Queue中

以下是两种方式开启任务的区别:
Operation 如果手动start开启,Operation对象内部是默认非并发地,也就是与start调用的线程是同步执行的,也就是会阻碍当前线程,如果想使用异步并发,必须在异步的并发队列中调用start才行。
当然也可以直接将Operation 添加到 一个初始化ok的Operation Queue中,Operation Queue会帮助你异步地调用start方法

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"1");        NSLog(@"===%@", [NSThread currentThread]);    }];    [op addExecutionBlock:^{        NSLog(@"2");        NSLog(@"%@", [NSThread currentThread]);    }];    [op addExecutionBlock:^{        NSLog(@"3");        NSLog(@"%@", [NSThread currentThread]);    }];    [op addExecutionBlock:^{        NSLog(@"4");        NSLog(@"%@", [NSThread currentThread]);    }];    [op setCompletionBlock:^{        NSLog(@"并发完成");    }];    NSLog(@"done");//    operation是非并发对象//    这样在主线程中执行的话,与主线程同步,输出 1、2、3、4乱序 再输出done    [op start];   //Operation线程 与 主线程 同步 ,非并发    //主线程与op属于并发(不知道是谁先运行)    //输出 1、2、3、4、done都是乱序的  属于并发    //第一种方式    [queue addOperation:op];  //异步执行,并发执行////    //第二种方式//    dispatch_async(dispatch_get_global_queue(0, 0), ^{////        [op start];  //这句代码和下句代码是线程同步的//        //        dispatch_async(dispatch_get_main_queue(), ^{//           //            NSLog(@"网络请求完成");//        });//        //    });

自定义Operation

如果系统子类化的Operation 无法满足您的需求,你可以自定义Operation,重写它的一些方法,达到你的目的。

1、定义非并发地Operation

2、定义并发地Operation (因为Operation默认是非并发的,必须添加到Operation queue或者并发队列中才能实现并发,如果你想手工实现并发地话,就必须自定义实现,设置isConcurrent为YES)

NSOperation key-value observing KVO key paths:

isCancelled
isConcurrent
isExecuting
isFinished
isReady
dependencies
queuePriority
completionBlock

设置Operation间的依赖

注意:依赖不能循环依赖

addDependency:

设置Operation优先级

setQueuePriority:

Operation Queue

创建Queue

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

添加Operation

[aQueue addOperation:anOp]; // Add a single operation[aQueue addOperations:anArrayOfOps waitUntilFinished:NO]; // Add multiple operations[aQueue addOperationWithBlock:^{ /* Do something. */}];

设置最大并发数

setMaxConcurrentOperationCount: 

取消Queue

cancelcancelAllOperations

挂起和继续Queue

setSuspended: 
0 0
原创粉丝点击