iOS 多線程--NSOperation

一眠砾、NSOperation介紹:基本語法

NSOperation在iOS4后也基于GCD實(shí)現(xiàn),但是相對(duì)于GCD來說可控性更強(qiáng)托酸,并且可以加入操作依賴褒颈。NSOperation是一個(gè)抽象類,系統(tǒng)為我們提供了NSBlockOperation和NSInvocationOperation兩個(gè)子類励堡,并且可以創(chuàng)建繼承自NSOperation的自定義類谷丸。相比于GCD,NSOperation類更加面向?qū)ο笥幔_發(fā)者除了不需要去了解線程相關(guān)的概念之外刨疼,甚至連GCD中需要了解的異步/同步、并行/串行都不太需要深入了解摊趾,開發(fā)者只要懂得任務(wù)和隊(duì)列即可币狠。

1、NSOperation的子類

由于NSOperation是一個(gè)抽象類砾层,因此不能夠直接使用NSOperation漩绵,但蘋果提供了兩個(gè)NSOperation的子類,NSBlockOperation和NSInvocationOperation肛炮,除此之外止吐,我們還可以自定義NSOperation的子類。

二侨糟、NSOperation介紹:線程間通信

在NSOperationQueue類中碍扔,也可以獲取主線程隊(duì)列,相關(guān)更新UI的任務(wù)必須放在主隊(duì)列中完成秕重。

下方示例中不同,當(dāng)點(diǎn)擊開始下載按鈕后,會(huì)創(chuàng)建一個(gè)NSBlockOperation對(duì)象溶耘,放在一個(gè)普通隊(duì)列中執(zhí)行二拐,開始下載網(wǎng)絡(luò)圖片。此時(shí)凳兵,由于下載任務(wù)是在非主線程中進(jìn)行的百新,所以界面上的switch按鈕是可以點(diǎn)擊的。等下載完成后庐扫,需要在下載任務(wù)中返回主線程去設(shè)置UI界面饭望。

Paste_Image.png
- (IBAction)startBtnAction:(id)sender {
    NSBlockOperation *downloadTask = [NSBlockOperation blockOperationWithBlock:^{
    //下載網(wǎng)絡(luò)圖片
    NSString *urlString = @"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRc3Rs3zHlmPEdusO8G_I1xHyKsYUujL9ZX76nfgkVVu69oU_gosw";
    NSURL *url = [NSURL URLWithString:urlString];
    NSData *imageData = [NSData dataWithContentsOfURL:url];
    UIImage *image = [UIImage imageWithData:imageData];
    //返回主線程設(shè)置ui
    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    [mainQueue addOperationWithBlock:^{
        self.imageView.image = image;
    }];
}];
//創(chuàng)建queue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:downloadTask];
}

三仗哨、NSOperation介紹:任務(wù)間的執(zhí)行依賴

NSOperation中提供了更加方便直觀的方式來設(shè)置任務(wù)執(zhí)行的先后順序關(guān)系。通過NSOperation類中的addDependency方法铅辞,即可添加任務(wù)的之間的依賴關(guān)系厌漂。由于addDependency是NSOperation類中的方法,與隊(duì)列無關(guān)巷挥,因此也可以針對(duì)不同隊(duì)列中的任務(wù)設(shè)置任務(wù)執(zhí)行的先后依賴關(guān)系桩卵。

下方的示例中,有3個(gè)任務(wù)依次順序執(zhí)行倍宾,先依次下載兩張圖片雏节,圖片下載完成后,需要返回主線程去更新界面上的UIImageView高职,等圖片下載并刷新界面完成后钩乍,第三個(gè)任務(wù)是更新界面上的下載狀態(tài)Label。這3個(gè)任務(wù)的執(zhí)行有先后依賴關(guān)系怔锌。

Paste_Image.png
- (IBAction)startBtnAction:(id)sender {
    //創(chuàng)建兩個(gè)任務(wù)寥粹,兩個(gè)任務(wù)完成后,返回主線程執(zhí)行第三個(gè)更新Label的任務(wù)
    NSBlockOperation *task1 = [NSBlockOperation blockOperationWithBlock:^{
        //下載圖片
        NSString *urlString = @"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRc3Rs3zHlmPEdusO8G_I1xHyKsYUujL9ZX76nfgkVVu69oU_gosw";
        NSURL *url = [NSURL URLWithString:urlString];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *image1 = [UIImage imageWithData:imageData];
    
        NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
        [mainQueue addOperationWithBlock:^{
            self.imageView1.image = image1;
        }];
    }];

    NSBlockOperation *task2 = [NSBlockOperation blockOperationWithBlock:^{
        //下載圖片
        NSString *urlString = @"https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQ6RwzhikGicc2R-tiySq7A1K8g40apnXtryI31CO3JxW7IEIUJ_Q";
        NSURL *url = [NSURL URLWithString:urlString];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *image2 = [UIImage imageWithData:imageData];
    
        NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
        [mainQueue addOperationWithBlock:^{
            self.imageView2.image = image2;
        }];
    
    }];
    NSBlockOperation *task3 = [NSBlockOperation blockOperationWithBlock:^{
        NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
        [mainQueue addOperationWithBlock:^{
           self.titleLab.text = @"下載完成";
        }];
    }];

    //設(shè)置任務(wù)之間的執(zhí)行依賴關(guān)系
    [task3 addDependency:task1];
    [task3 addDependency:task2];
    [task2 addDependency:task1];
    //創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //添加任務(wù)到隊(duì)列
    [queue addOperation:task1];
    [queue addOperation:task2];
    [queue addOperation:task3];
}

四埃元、NSOperation與GCD的區(qū)別

  • GCD是底層的C語言構(gòu)成的API涝涤,而NSOperationQueue及相關(guān)對(duì)象是Objc的對(duì)象。在GCD中岛杀,在隊(duì)列中執(zhí)行的是由block構(gòu)成的任務(wù)阔拳,這是一個(gè)輕量級(jí)的數(shù)據(jù)結(jié)構(gòu);而NSOperation作為一個(gè)對(duì)象类嗤,為我們提供了更多的選擇糊肠;
  • 在NSOperationQueue中,我們可以隨時(shí)取消已經(jīng)設(shè)定要準(zhǔn)備執(zhí)行的任務(wù)(當(dāng)然遗锣,已經(jīng)開始的任務(wù)就無法阻止了)货裹,而GCD沒法停止已經(jīng)加入queue的block(其實(shí)是有的,但需要許多復(fù)雜的代碼)精偿;
  • NSOperation能夠方便地設(shè)置依賴關(guān)系弧圆,我們可以讓一個(gè)Operation依賴于另一個(gè)Operation,這樣的話盡管兩個(gè)Operation處于同一個(gè)并行隊(duì)列中笔咽,但前者會(huì)直到后者執(zhí)行完畢后再執(zhí)行墓阀;
    我們能將KVO應(yīng)用在NSOperation中,可以監(jiān)聽一個(gè)Operation是否完成或取消拓轻,這樣子能比GCD更加有效地掌控我們執(zhí)行的后臺(tái)任務(wù);
  • 在NSOperation中经伙,我們能夠設(shè)置NSOperation的priority優(yōu)先級(jí)扶叉,能夠使同一個(gè)并行隊(duì)列中的任務(wù)區(qū)分先后地執(zhí)行勿锅,而在GCD中,我們只能區(qū)分不同任務(wù)隊(duì)列的優(yōu)先級(jí)枣氧,如果要區(qū)分block任務(wù)的優(yōu)先級(jí)溢十,也需要大量的復(fù)雜代碼;
  • 我們能夠?qū)SOperation進(jìn)行繼承达吞,在這之上添加成員變量與成員方法张弛,提高整個(gè)代碼的復(fù)用度,這比簡單地將block任務(wù)排入執(zhí)行隊(duì)列更有自由度酪劫,能夠在其之上添加更多自定制的功能吞鸭。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市覆糟,隨后出現(xiàn)的幾起案子刻剥,更是在濱河造成了極大的恐慌,老刑警劉巖滩字,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件造虏,死亡現(xiàn)場離奇詭異,居然都是意外死亡麦箍,警方通過查閱死者的電腦和手機(jī)漓藕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挟裂,“玉大人享钞,你說我怎么就攤上這事』扒疲” “怎么了嫩与?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長交排。 經(jīng)常有香客問我划滋,道長,這世上最難降的妖魔是什么埃篓? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任处坪,我火速辦了婚禮,結(jié)果婚禮上架专,老公的妹妹穿的比我還像新娘同窘。我一直安慰自己,他們只是感情好部脚,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布想邦。 她就那樣靜靜地躺著,像睡著了一般委刘。 火紅的嫁衣襯著肌膚如雪丧没。 梳的紋絲不亂的頭發(fā)上鹰椒,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音呕童,去河邊找鬼漆际。 笑死,一個(gè)胖子當(dāng)著我的面吹牛夺饲,可吹牛的內(nèi)容都是我干的奸汇。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼往声,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼擂找!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烁挟,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤婴洼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后撼嗓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柬采,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年且警,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粉捻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斑芜,死狀恐怖肩刃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杏头,我是刑警寧澤盈包,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站醇王,受9級(jí)特大地震影響呢燥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寓娩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一叛氨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棘伴,春花似錦寞埠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阱穗,卻和暖如春怖糊,著一層夾襖步出監(jiān)牢的瞬間帅容,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國打工伍伤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遣钳。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓扰魂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蕴茴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子劝评,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

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

  • 和GCD的對(duì)比 操作隊(duì)列,比GCD更早倦淀,GCD在設(shè)計(jì)上很多都是基于操作隊(duì)列的原理構(gòu)建的蒋畜。在iOS4之后,操作隊(duì)列的...
    doudo閱讀 187評(píng)論 0 0
  • 1. NSOperation簡介 在某些情況下撞叽,執(zhí)行后臺(tái)任務(wù)GCD不一定是最好的方式姻成,還有一種技術(shù)叫做操作隊(duì)列NS...
    Claire_wu閱讀 1,049評(píng)論 0 0
  • NSOperation是蘋果提供給我們的一套多線程解決方案。實(shí)際上它是在ios4后基于GCD開發(fā)的愿棋,但是比GCD擁...
    艷曉閱讀 223評(píng)論 0 2
  • 一科展、簡介 NSOperation 的作用NSOperation 是對(duì) GCD 的一層封裝,更加面向?qū)ο蟆?配合使用...
    hrscy閱讀 446評(píng)論 0 3
  • 世界上最深情的話,往往都是普通的日常用語甘邀。 我爸不抽煙不喝酒不賭博琅攘。但我最近發(fā)現(xiàn),我爸可能是“毒爸”松邪。 對(duì)子女“有...
    看賞閱讀 882評(píng)論 3 5