iOS多線程梳理-NSOperation

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

NSOperation

NSOperation 是蘋果公司對(duì) GCD 的封裝秕豫,面向?qū)ο蟆?NSOperation 和 NSOperationQueue 分別對(duì)應(yīng) GCD 的 任務(wù) 和 隊(duì)列 。使用如下:
1.將要執(zhí)行的任務(wù)封裝到一個(gè) NSOperation 對(duì)象中
2.將此任務(wù)添加到一個(gè) NSOperationQueue 對(duì)象中

添加任務(wù)

NSOperation 是一個(gè)抽象類,所以不能封裝任務(wù)熟空。但它有 2 個(gè)子類用于封裝任務(wù)。分別是:NSInvocationOperation 和 NSBlockOperation 。創(chuàng)建一個(gè) Operation 后,需要調(diào)用 start 方法來(lái)啟動(dòng)任務(wù)焦辅,它會(huì) 默認(rèn)在當(dāng)前隊(duì)列同步執(zhí)行。當(dāng)然也可以在中途取消一個(gè)任務(wù)椿胯,只需要調(diào)用其 cancel 方法即可筷登。

  //1.創(chuàng)建NSBlockOperation對(duì)象
  NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
      NSLog(@"task %@", [NSThread currentThread]);
  }];
  //2.開始任務(wù)
  [operation start];

NSBlockOperation 還有一個(gè)方法:addExecutionBlock: ,通過這個(gè)方法可以給 Operation 添加多個(gè)執(zhí)行 Block哩盲,并且addExecutionBlock添加的Block 會(huì)并發(fā)異步執(zhí)行前方。如下:

    NSLog(@"beagin %@",[NSThread currentThread]);
    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{//當(dāng)前線程
       sleep(2);
        NSLog(@"first %@",[NSThread currentThread]);
    }];
    for (NSInteger i=0; i<3; i++) {
        [blockOp addExecutionBlock:^{//其他線程
            sleep(2);
            NSLog(@"section %@",[NSThread currentThread]);
        }];
    }
    [blockOp start];
/*輸出結(jié)果:
     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}
*/

創(chuàng)建隊(duì)列NSOperation

  • 主隊(duì)列

    NSOperationQueue *mQueue = [NSOperationQueue mainQueue];
    
  • 其他隊(duì)列
    因?yàn)橹麝?duì)列比較特殊,所以會(huì)單獨(dú)有一個(gè)類方法來(lái)獲得主隊(duì)列种冬。那么通過初始化產(chǎn)生的隊(duì)列就是其他隊(duì)列了

  • 串行隊(duì)列
    NSOperationQueue 有一個(gè)參數(shù) maxConcurrentOperationCount 最大并發(fā)數(shù)镣丑,可以用來(lái)設(shè)置最多可以讓多少個(gè)任務(wù)同時(shí)執(zhí)行舔糖。當(dāng)把它設(shè)置為 1 的時(shí)候娱两,就是為串行隊(duì)列

任務(wù)依賴案例:

    //有 3 個(gè)任務(wù):A: 從服務(wù)器上下載一張圖片,B:給這張圖片加個(gè)水印金吗,C:把圖片返回給服務(wù)器
    //1.任務(wù)一:下載圖片
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下載圖片 - %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //2.任務(wù)二:打水印
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"打水印   - %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //3.任務(wù)三:上傳圖片
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"上傳圖片 - %@", [NSThread currentThread]);
        [NSThread sleepForTimeInterval:1.0];
    }];
    //4.設(shè)置依賴
    [operation2 addDependency:operation1];      //任務(wù)二依賴任務(wù)一
    [operation3 addDependency:operation2];      //任務(wù)三依賴任務(wù)二
    //5.創(chuàng)建隊(duì)列并加入任務(wù)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:YES];
    NSLog(@"其他task");
/*輸出結(jié)果:
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摇庙,這樣會(huì)死鎖
  • 可以使用 removeDependency 來(lái)解除依賴關(guān)系
  • addOperations:waitUntilFinished:當(dāng)傳入YES時(shí)會(huì)阻塞旱物,等待任務(wù)完畢后才會(huì)繼續(xù)往下執(zhí)行

指定并發(fā)數(shù)量的多任務(wù)執(zhí)行案例:

    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];
    }
/*輸出結(jié)果:
     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)}
*/

通過打印的時(shí)間我們可以看到最多只有兩條線程同時(shí)異步執(zhí)行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卫袒,一起剝皮案震驚了整個(gè)濱河市宵呛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夕凝,老刑警劉巖宝穗,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件户秤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡逮矛,警方通過查閱死者的電腦和手機(jī)鸡号,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)须鼎,“玉大人鲸伴,你說(shuō)我怎么就攤上這事飞苇》Π拢” “怎么了且警?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵峦嗤,是天一觀的道長(zhǎng)庵寞。 經(jīng)常有香客問我轿塔,道長(zhǎng)鼓寺,這世上最難降的妖魔是什么班缰? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任捶朵,我火速辦了婚禮蜘矢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘综看。我一直安慰自己品腹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布红碑。 她就那樣靜靜地躺著舞吭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪析珊。 梳的紋絲不亂的頭發(fā)上羡鸥,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音忠寻,去河邊找鬼惧浴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奕剃,可吹牛的內(nèi)容都是我干的衷旅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纵朋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼柿顶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起操软,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嘁锯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體家乘,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品山,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烤低。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肘交。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖扑馁,靈堂內(nèi)的尸體忽然破棺而出涯呻,到底是詐尸還是另有隱情,我是刑警寧澤腻要,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布复罐,位于F島的核電站,受9級(jí)特大地震影響雄家,放射性物質(zhì)發(fā)生泄漏效诅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一趟济、第九天 我趴在偏房一處隱蔽的房頂上張望乱投。 院中可真熱鬧,春花似錦顷编、人聲如沸戚炫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)双肤。三九已至,卻和暖如春钮惠,著一層夾襖步出監(jiān)牢的瞬間茅糜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工素挽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔑赘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓毁菱,卻偏偏與公主長(zhǎng)得像米死,于是被迫代替她去往敵國(guó)和親锌历。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贮庞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容