1、NSOperation的两个子类NSBlockOperation与NSInvocationOperation,前者通过Block实现队列执行体,后者通过调用方法实现。
2、创建好NSOperation任务后,加入到系统队列,分为自定义队列即通过NSOperationQueue创建,或加入到主队列[NSOperationQueue mainQueue]
3、以上两步即可搞定,NSOperation/NSOperationQueue中程序不需要关心同步/异步、串行/并行问题,由框架自动处理,因此使用起来更方便更安全。
4、操作任务一添加到队列中即会执行,这一点与GCD不同。
5、如果需要指定任务的先后执行任务,可使用NSOperation的 addDependency: 方法,如 [op2 addDependency:op1]表示op2依赖于op1,因此会在op1后被执行。(注意不要出现循环依赖)
6、如果需要限制线程数,可通过NSOperationQueue的 setMaxConcurrentOperationCount: 方法实现,如图片下载任务在WiFi环境中线程数为6,3G环境中为3
关键代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // 创建一个自定义队列 @property (nonatomic, strong) NSOperationQueue *myQueue; // 初始化自定义队列 self.myQueue = [[NSOperationQueue alloc] init]; #pragma mrak 1、Block队列操作 - (void)blockOperation { // 循环10次添加10个任务到自定义队列 for (int i = 0; i < 10; i++) { // 创建一个操作任务,不需要关心串行并行等问题 NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{ // 每执行一次任务,输出该任务的添加序号及线程对象 NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]); }]; // 将任务添加到自定义队列中,默认将异步并行执行 [self.myQueue addOperation:blockOp]; // 将任务添加到主队列中,即在主线程中执行 // [[NSOperationQueue mainQueue] addOperation:blockOp]; } } #pragma mark 2、invocation队列操作 - (void)invocationOperation { for (int i = 0; i < 10; i++) { // 与NSBlockOperation类似,唯一不同的是这里通过调用方法实现队列执行体 NSInvocationOperation *invocationOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction:) object:@(i)]; [self.myQueue addOperation:invocationOp]; // [[NSOperationQueue mainQueue] addOperation:invocationOp]; } } #pragma mark 调用方法 - (void)operationAction:(id)obj { NSLog(@"第 %d 次 - %@", [obj intValue], [NSThread currentThread]); } |
Demo下载:Test