iOS多線程(一):NSInvocationOperation 和 NSBlockOperation 使用

1 NSOperation

NSOperation 自身是一個抽象類恨闪,定義了一個要執(zhí)行的工作监署,可以定義一個 NSOperation 的子類來使用痘昌,只需要實現(xiàn) NSOperation 的main方法,通過start方法來執(zhí)行任務淹办,默認是同步執(zhí)行的,而如果需要支持并發(fā)工作舍沙,那么 NSOperation 子類還需要重寫其他方法怎栽。

但是對于大多數(shù)業(yè)務來說,只需要使用系統(tǒng)定義的 NSOperation 的兩個子類NSInvocationOperationNSBlockOperation配合NSOperationQueue即可達到我們的需求阀捅。自定義 NSOperation 子類的方法后文再介紹胀瞪。

2 NSInvocationOperation

先來看看基本用法

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 可以傳遞一個 NSObject 給operation的操作方法
    NSDictionary *dict = [NSDictionary dictionaryWithObject:@"value1" forKey:@"key1"];
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationSelector:) object:dict];
    NSLog(@"start before");
    [op start];
    NSLog(@"start after");
}

// NSInvocationOperation 操作執(zhí)行的方法
- (void)operationSelector:(NSDictionary *)dict
{
    // 接收傳進來的dict
    NSLog(@"dictValue = %@", [dict valueForKey:@"key1"]);
    sleep(10);  // 加個睡眠模仿耗時操作
    NSLog(@"currentThread = %@", [NSThread currentThread]);
    NSLog(@"mainThread = %@", [NSThread mainThread]);
}

注意start方法是在主線程執(zhí)行的,控制臺輸出如下

2015-12-24 12:51:48.369 test[32228:16046453] start before
2015-12-24 12:51:48.369 test[32228:16046453] dictValue = value1
2015-12-24 12:51:58.369 test[32228:16046453] currentThread = <NSThread: 0x7fbfc0600a50>{number = 1, name = main}
2015-12-24 12:51:58.370 test[32228:16046453] mainThread    = <NSThread: 0x7fbfc0600a50>{number = 1, name = main}
2015-12-24 12:51:58.370 test[32228:16046453] start after

從輸出結果可以看出饲鄙,執(zhí)行的操作方法與調用start的方法在同一個線程凄诞,并且是同步執(zhí)行的。

3 NSBlockOperation

3.1 NSBlockOperation 的基本用法

NSBlockOperation 的使用也非常簡單

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        sleep(10);  // 加個睡眠模仿耗時操作
        NSLog(@"currentThread = %@", [NSThread currentThread]);
        NSLog(@"mainThread = %@", [NSThread mainThread]);
    }];
    NSLog(@"start before");
    [op start];
    NSLog(@"start after");
}

控制臺輸出結果如下

2015-12-24 13:01:46.440 test[91193:16257301] start before
2015-12-24 13:01:56.442 test[91193:16257301] currentThread = <NSThread: 0x7fd9aac03f30>{number = 1, name = main}
2015-12-24 13:01:56.442 test[91193:16257301] mainThread    = <NSThread: 0x7fd9aac03f30>{number = 1, name = main}
2015-12-24 13:01:56.442 test[91193:16257301] start after

可以看出忍级,NSBlockOperation 與 NSInvocationOperation 的結果是一樣的帆谍,Block 中的操作與start方法在同一個線程執(zhí)行,并且是同步執(zhí)行的轴咱。

3.2 NSBlockOperation 多線程異步執(zhí)行

NSBlockOperation 還提供了這個方法

- (void)addExecutionBlock:(void (^)(void))block;

在上面的代碼基礎上擴展一下

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"BlockOperation 1 begin");
        sleep(10);  // 加個睡眠模仿耗時操作
        NSLog(@"BlockOperation 1 currentThread = %@", [NSThread currentThread]);
        NSLog(@"BlockOperation 1 mainThread    = %@", [NSThread mainThread]);
        NSLog(@"BlockOperation 1 end");
    }];
    [op addExecutionBlock:^{
        NSLog(@"BlockOperation 2 begin");
        sleep(10);
        NSLog(@"BlockOperation 2 currentThread = %@", [NSThread currentThread]);
        NSLog(@"BlockOperation 2 mainThread    = %@", [NSThread mainThread]);
        NSLog(@"BlockOperation 2 end");
    }];
    [op addExecutionBlock:^{
        NSLog(@"BlockOperation 3 begin");
        sleep(10);
        NSLog(@"BlockOperation 3 currentThread = %@", [NSThread currentThread]);
        NSLog(@"BlockOperation 3 mainThread    = %@", [NSThread mainThread]);
        NSLog(@"BlockOperation 3 end");
    }];
    
    NSLog(@"start before");
    [op start];
    NSLog(@"start after");
}

控制臺輸出結果

2015-12-24 13:12:33.720 test[91459:16314387] start before
2015-12-24 13:12:33.720 test[91459:16314387] BlockOperation 1 begin
2015-12-24 13:12:33.720 test[91459:16314433] BlockOperation 3 begin
2015-12-24 13:12:33.720 test[91459:16314432] BlockOperation 2 begin
2015-12-24 13:12:43.725 test[91459:16314387] BlockOperation 1 currentThread = <NSThread: 0x7fee1b507ef0>{number = 1, name = main}
2015-12-24 13:12:43.726 test[91459:16314387] BlockOperation 1 mainThread    = <NSThread: 0x7fee1b507ef0>{number = 1, name = main}
2015-12-24 13:12:43.726 test[91459:16314387] BlockOperation 1 end
2015-12-24 13:12:43.786 test[91459:16314433] BlockOperation 3 currentThread = <NSThread: 0x7fee1ea08010>{number = 2, name = (null)}
2015-12-24 13:12:43.786 test[91459:16314432] BlockOperation 2 currentThread = <NSThread: 0x7fee1b407cf0>{number = 3, name = (null)}
2015-12-24 13:12:43.786 test[91459:16314432] BlockOperation 2 mainThread    = <NSThread: 0x7fee1b507ef0>{number = 1, name = (null)}
2015-12-24 13:12:43.786 test[91459:16314433] BlockOperation 3 mainThread    = <NSThread: 0x7fee1b507ef0>{number = 1, name = (null)}
2015-12-24 13:12:43.786 test[91459:16314432] BlockOperation 2 end
2015-12-24 13:12:43.786 test[91459:16314433] BlockOperation 3 end
2015-12-24 13:12:43.786 test[91459:16314387] start after

看到 Block2 和 Block3 中的 currentThread 并不是主線程汛蝙,而且其中的操作也是異步執(zhí)行的。

可以看出如果是通過addExecutionBlock添加的操作則是多線程異步操作朴肺。

@property (readonly, copy) NSArray<void (^)(void)> *executionBlocks;

這個只讀屬性得到添加進 NSBlockOperation 的所有 Block 窖剑,包括第一個。

4 總結

對于這兩個 Operation 戈稿,如果僅使用同步執(zhí)行操作西土,那么并沒有多大的區(qū)別,一個是使用 selector 回調并可以傳遞參數(shù)進去鞍盗,一個是使用 Block 需了,可根據(jù)實際情況選擇。

但是如果想要使用多線程異步操作橡疼,則應該選擇 NSBlockOperation援所,不過注意只有通過addExecutionBlock添加的操作才是多線程異步操作。

關于 NSInvocationOperation 和 NSBlockOperation 使用先介紹到這里欣除。下一篇我們通過自定義NSOperation的子類住拭,來實現(xiàn)更加靈活的方法。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末历帚,一起剝皮案震驚了整個濱河市滔岳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挽牢,老刑警劉巖谱煤,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異禽拔,居然都是意外死亡刘离,警方通過查閱死者的電腦和手機室叉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硫惕,“玉大人茧痕,你說我怎么就攤上這事∧粘” “怎么了踪旷?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長豁辉。 經(jīng)常有香客問我令野,道長,這世上最難降的妖魔是什么徽级? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任气破,我火速辦了婚禮,結果婚禮上灰追,老公的妹妹穿的比我還像新娘堵幽。我一直安慰自己,他們只是感情好弹澎,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著殴胧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灸姊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天弄跌,我揣著相機與錄音铛只,去河邊找鬼押袍。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的驱敲。 我是一名探鬼主播容诬,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纽什,長吁一口氣:“原來是場噩夢啊……” “哼枫慷!你這毒婦竟也來了?” 一聲冷哼從身側響起流礁,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤涕俗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后神帅,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再姑,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年找御,在試婚紗的時候發(fā)現(xiàn)自己被綠了元镀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绍填。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖栖疑,靈堂內的尸體忽然破棺而出讨永,到底是詐尸還是另有隱情,我是刑警寧澤遇革,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布卿闹,位于F島的核電站,受9級特大地震影響萝快,放射性物質發(fā)生泄漏锻霎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一揪漩、第九天 我趴在偏房一處隱蔽的房頂上張望旋恼。 院中可真熱鬧,春花似錦奄容、人聲如沸冰更。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜀细。三九已至,卻和暖如春叁怪,著一層夾襖步出監(jiān)牢的瞬間审葬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工奕谭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涣觉,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓血柳,卻偏偏與公主長得像官册,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子难捌,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容