标签:
//子类CNOperation的创建继承NSOperation
CNOperation* op = [[CNOperation alloc]init];
//NSOperation默认并不会执行,必须调用start方法
[op start];
#import "CNOperation.h"
@implementation CNOperation - (void)main{
NSLog(@"do something");
} @end
|
1.创建NSInvocationOperation
NSInvocationOperation* iop = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invoAction) object:nil];
[iop start];
|
2.创建NSBlockOperation
1.系统block
NSBlockOperation* bop = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"do other something");
}]; [bop start];
2.自定义block
//在CNOperation类中自己写block也可以
@property(copy)void(^block)(void);
//在CNOperation类中的main方法中调用block
- (void)main{
//调用block if (_block) { _block(); }
CNOperation* cn = [[CNOperation alloc]init];
//block实现 [cn setBlock:^{ NSLog(@"do something");
//死循环
// while(true){
//
// }
}];
[cn start];
// NSLog(@“因为有死循环,所以该语句永远不会被打印出来”);
小结:
NSOperation默认并不会执行,必须调用start方法,执行时默认在当前线程中执行,即 默认同步执行。
什么实同步执行呢?
就是block执行不完,start就不会执行
怎样调用的呢?
比如在上面的代码中,默认程序先走到start,start又调用的main,main又调用的block ,层层调用,后调用的先执行,所以block先执行start后执行,先打印do something
|
CNOperation* cn = [[CNOperation alloc]init];
//block实现 [cn setBlock:^{ NSLog(@"do something"); //死循环 while (true) { }
}];
//同步执行(在当前线程执行op任务),该start永远不会被执行,因为block中有死循环,block执行不完,start不会被执行 // [cn start]; //异步执行(在其他线程执行op任务), 该start不会被执行,后面的代码会被打印,因为异步执行是不管block执不执行完,start都会执行
//异步执行只需要将start方法放到新的线程中调用,该performSelectorInBackground是隐式创建的线程,我们都没有办法管理他,所以我们用queue来创建新的线程,这就是新学的内容
[cn performSelectorInBackground:@selector(start) withObject:nil];
NSLog(@"aaa");
|
1.创建NSOperationQueue
//创建线程管理器
NSOperationQueue* opQ = [[NSOperationQueue alloc]init];
|
2.添加单个operation到queue中
NSBlockOperation* bop1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"bop1......"); NSLog(@"bop1:%@",[NSThread currentThread]); // usleep(1000000); }]; //添加到queue后,不需要手动start,会自动开始执行 // [bop1 start]; NSBlockOperation* bop2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"bop2......."); NSLog(@"bop2:%@",[NSThread currentThread]); // usleep(1000000); }]; // [bop2 start]; //添加到Queue中的NSOperation会自动执行,执行的时间取决于两个因素一个是依赖。一个是优先级 // [opQ addOperation:bop1]; // [opQ addOperation:bop2];
|
3.可以同时添加多个Operation到Queue中
//可以同时添加多个Operation到Queue中
//waitUntilFinished设置为NO就是不用等待queue全部执行完就可以执行后面的语句--ok---
//waitUntilFinished设置为YES就是等待queue全部执行完后才可以执行后面的语句 [opQ addOperations:@[bop1,bop2] waitUntilFinished:YES];
NSLog(@"-----OK-----");
|
4.队列的最大并发数
//设置队列的最大并发数
//最大并行数为1时,所有的op都会串行,并不代表只有一个线程1-1-2-2
opQ.maxConcurrentOperationCount = 1;
/ / 若不设置最大并发书打印的operation可能会交替出现2-1-2-1
|
5. 可以隐式的添加一个Operation到Queue中
意思是不需要自己创建一个operation,而是让queue自己创建
[opQ addOperationWithBlock:^{
NSLog(@"可以隐式的添加一个Operation到Queue中");
NSLog(@"keyi:%@",[NSThread currentThread]); // usleep(1000000); }];
|
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^()
{
NSLog(@"执?行第1次操作,1:%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^()
{
NSLog(@"执?行第2次操作,2:%@", [NSThread currentThread]);
}]; NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^() {
NSLog(@"执?行第3次操作,3:%@", [NSThread currentThread]);
}]; //添加依赖
//依赖关系会影响到NSOperation对象在queue中的执行顺序
//添加依赖成功的前提,必须将Operation添加到Queue中
/ / 添加依赖后默认会在同一个线程中执行,不完全对
[operation1 addDependency:operation2];
[operation1 addDependency:operation3];
//添加多个依赖后,上边的话就不对,而应该改为operation1会在最后执行的依赖operation执行的线程中执行
//意思是op2依赖于op1所以op2先执行,而op3依赖于op1所以op3先执行,那么op2和op3谁先执行呢?op3和op2不一定谁先执行,op1会在依赖的最后一个线程中执行,因为当前打印中op2最后执行,所以op1和op2是在同一个线程
|
//设置优先级
//首先根据依赖关系,确定前后执行顺序,其次在满足依赖关系的前提下,再根据优先级排序。 operation2.qualityOfService = NSQualityOfServiceUserInteractive; operation3.qualityOfService = NSQualityOfServiceBackground; // |
// //注意:不能创建环形依赖,比如A依赖B,B依赖A,这是错误的,
// [operation2 addDependency:operation1];
//op2执行不完op1不能执行,op1执行不完op2不能执行
|
//添加到queue之前添加依赖
//打印出来的执行顺序不确定 //添加到queue中的operation不应该再去修改属性 [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperation:operation3];
|
NSOperationQueue* queue = [[NSOperationQueue alloc]init];
NSBlockOperation* op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"block opreation1"); NSLog(@"1:%@",[NSThread currentThread]); }]; NSBlockOperation* op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"block opreation2"); NSLog(@"2:%@",[NSThread currentThread]); //取消op1 必须在op1执行前取消,否者无效 // [op1 cancel]; //暂停,,不是operation暂停和继续,任务开始后无法暂停取消,而是queue暂停和取消,暂停queue,不会暂停当前正在执行的operation,而是一直执行完,暂停只是会停止开启新的在等待的operation
// [queue setSuspended:YES];
//因为operation2正在执行,所以不会被暂停,而operation1被暂停
}]; //没添加依赖前,op开始执行后无法取消,仍然把op1和op2都执行出来
/ /但是添加依赖后就不一样了,添加依赖后op2先执行,此时op1还没有执行,这是就可以取消op1了
[op1 addDependency:op2];
[queue addOperation:op1]; [queue addOperation:op2]; |
//取消queue中的所有的操作
// [queue cancelAllOperations]; |
//等待卡死当前线程
//等待op2执行完毕后,再执行 // [op2 waitUntilFinished];
//等待queue所有操作执行完毕后执行
[queue waitUntilAllOperationsAreFinished]; NSLog(@".........."); |
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//延时3秒后继续queue [queue setSuspended:NO]; });
|
标签:
原文地址:http://www.cnblogs.com/gaominmin/p/4821511.html