iOS多线程梳理-NSOperation

上一篇 iOS多线程梳理-GCD(3)

NSOperation

NSOperation 是苹果公司对 GCD 的封装,面向对象。 NSOperation 和 NSOperationQueue 分别对应 GCD 的 任务 和 队列 。使用如下:
1.将要执行的任务封装到一个 NSOperation 对象中
2.将此任务添加到一个 NSOperationQueue 对象中

添加任务

NSOperation 是一个抽象类,所以不能封装任务。但它有 2 个子类用于封装任务。分别是:NSInvocationOperation 和 NSBlockOperation 。创建一个 Operation 后,需要调用 start 方法来启动任务,它会 默认在当前队列同步执行。当然也可以在中途取消一个任务,只需要调用其 cancel 方法即可。

  //1.创建NSBlockOperation对象
  NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
      NSLog(@"task %@", [NSThread currentThread]);
  }];
  //2.开始任务
  [operation start];

NSBlockOperation 还有一个方法:addExecutionBlock: ,通过这个方法可以给 Operation 添加多个执行 Block,并且addExecutionBlock添加的Block 会并发异步执行。如下:

    NSLog(@"beagin %@",[NSThread currentThread]);
    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{//当前线程
       sleep(2);
        NSLog(@"first %@",[NSThread currentThread]);
    }];
    for (NSInteger i=0; i<3; i++) {
        [blockOp addExecutionBlock:^{//其他线程
            sleep(2);
            NSLog(@"section %@",[NSThread currentThread]);
        }];
    }
    [blockOp start];
/*输出结果:
     2017-10-12 17:15:30.638732+0800 GCDLearnAdvanced[5362:776321] beagin <NSThread: 0x608000076000>{number = 1, name = main}
     2017-10-12 17:15:32.640445+0800 GCDLearnAdvanced[5362:776360] section <NSThread: 0x60c000466e40>{number = 5, name = (null)}
     2017-10-12 17:15:32.640444+0800 GCDLearnAdvanced[5362:776363] section <NSThread: 0x60c000467a00>{number = 3, name = (null)}
     2017-10-12 17:15:32.640445+0800 GCDLearnAdvanced[5362:776361] section <NSThread: 0x600000270a00>{number = 4, name = (null)}
     2017-10-12 17:15:32.640469+0800 GCDLearnAdvanced[5362:776321] first <NSThread: 0x608000076000>{number = 1, name = main}
*/

创建队列NSOperation

  • 主队列

    NSOperationQueue *mQueue = [NSOperationQueue mainQueue];
    
  • 其他队列
    因为主队列比较特殊,所以会单独有一个类方法来获得主队列。那么通过初始化产生的队列就是其他队列了

  • 串行队列
    NSOperationQueue 有一个参数 maxConcurrentOperationCount 最大并发数,可以用来设置最多可以让多少个任务同时执行。当把它设置为 1 的时候,就是为串行队列

任务依赖案例:

    //有 3 个任务:A: 从服务器上下载一张图片,B:给这张图片加个水印,C:把图片返回给服务器
    //1.任务一:下载图片
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片 - %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //2.任务二:打水印
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"打水印   - %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //3.任务三:上传图片
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"上传图片 - %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //4.设置依赖
    [operation2 addDependency:operation1];      //任务二依赖任务一
    [operation3 addDependency:operation2];      //任务三依赖任务二
    //5.创建队列并加入任务
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:YES];
    NSLog(@"其他task");
/*输出结果:
2017-10-12 17:33:27.035147+0800 GCDLearnAdvanced[5494:803023] 下载图片 - <NSThread: 0x600000274dc0>{number = 3, name = (null)}
2017-10-12 17:33:28.039947+0800 GCDLearnAdvanced[5494:803025] 打水印   - <NSThread: 0x60c000266e80>{number = 4, name = (null)}
2017-10-12 17:33:29.043323+0800 GCDLearnAdvanced[5494:803025] 上传图片 - <NSThread: 0x60c000266e80>{number = 4, name = (null)}
2017-10-12 17:33:30.048417+0800 GCDLearnAdvanced[5494:802986] 其他task
*/
  • 不能相互依赖,比如A依赖B,B依赖A,这样会死锁
  • 可以使用 removeDependency 来解除依赖关系
  • addOperations:waitUntilFinished:当传入YES时会阻塞,等待任务完毕后才会继续往下执行

指定并发数量的多任务执行案例:

    NSLog(@"beagin %@",[NSThread currentThread]);
    NSOperationQueue *operationQ = [[NSOperationQueue alloc]init];
    operationQ.maxConcurrentOperationCount = 2;
    for (NSInteger i=0; i<5; i++) {
        NSBlockOperation *blockOp = [[NSBlockOperation alloc]init];
        [blockOp addExecutionBlock:^{
            sleep(2);
            NSLog(@"first%@ %@",@(i),[NSThread currentThread]);
        }];
        [operationQ addOperation:blockOp];
    }
/*输出结果:
     2017-10-12 16:55:18.363146+0800 GCDLearnAdvanced[5194:730174] beagin <NSThread: 0x60c00006ed40>{number = 1, name = main}
     2017-10-12 16:55:20.364293+0800 GCDLearnAdvanced[5194:730224] first0 <NSThread: 0x60400007f700>{number = 3, name = (null)}
     2017-10-12 16:55:20.364293+0800 GCDLearnAdvanced[5194:730228] first1 <NSThread: 0x6080002722c0>{number = 4, name = (null)}
     2017-10-12 16:55:22.368552+0800 GCDLearnAdvanced[5194:730225] first2 <NSThread: 0x600000269a00>{number = 5, name = (null)}
     2017-10-12 16:55:22.368552+0800 GCDLearnAdvanced[5194:730221] first3 <NSThread: 0x60400007d880>{number = 6, name = (null)}
     2017-10-12 16:55:24.372538+0800 GCDLearnAdvanced[5194:730228] first4 <NSThread: 0x6080002722c0>{number = 4, name = (null)}
*/

通过打印的时间我们可以看到最多只有两条线程同时异步执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容