《iOS高級(jí)開發(fā)之多線程編程之三》

主隊(duì)列上的同步異步執(zhí)行

  • 主隊(duì)列 異步執(zhí)行 在主線程有序執(zhí)行
    dispatch_queue_t queue = dispatch_get_main_queue();
    for (int i = 0; i < 10; i++) {

      dispatch_async(queue, ^{
          NSLog(@"hello---%d %@",i,[NSThread currentThread]);
      });
      
     }
    
主隊(duì)列 異步執(zhí)行.png
  • 主隊(duì)列 同步執(zhí)行 在主線程上執(zhí)行時(shí)會(huì)死鎖

    dispatch_queue_t queue = dispatch_get_main_queue();
      //測(cè)試執(zhí)行
      NSLog(@"begin");
    
      for (int i = 0; i < 10; i++) {
     dispatch_sync(queue, ^{
         NSLog(@"hello --- %@",[NSThread currentThread]);
     });
      }
      //測(cè)試執(zhí)行
      NSLog(@"end");
    
主隊(duì)列 同步執(zhí)行.png
分析

從運(yùn)行結(jié)果可以明顯看出刨秆,程序無(wú)法正常執(zhí)行 被死鎖。
接下來(lái)看一下鎖死的原因:
當(dāng)程序運(yùn)行到下面這段代碼時(shí)
<pre> dispatch_sync(queue, ^{
NSLog(@"hello --- %@",[NSThread currentThread]);
}); </pre>
主線程:如果主線程正在執(zhí)行行代碼图柏,就不調(diào)度任務(wù)
同步執(zhí)行: 如果第一個(gè)任務(wù)沒(méi)有執(zhí)行立哑,就等待第一個(gè)任務(wù)執(zhí)行完成后彤钟,在執(zhí)行下一個(gè)任務(wù)。導(dǎo)致程序互相等待,造成死鎖仆百。

解決方案

(主隊(duì)列 同步執(zhí)行)放入異步執(zhí)行糖权,解決死鎖問(wèn)題

 dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_queue_t queue1 = dispatch_get_global_queue(0, 0);
//測(cè)試執(zhí)行
NSLog(@"begin");
dispatch_async(queue1, ^{
    for (int i = 0; i <10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"hello---%d %@",i,[NSThread currentThread]);
        });
    }
});
//測(cè)試執(zhí)行
NSLog(@"end");
Snip20170409_6.png

知識(shí)拓展

  • 主隊(duì)列于串行隊(duì)列的區(qū)別
  • 串行隊(duì)列: 必須的一個(gè)任務(wù)調(diào)度完成堵腹,再去執(zhí)行另一個(gè)任務(wù)
  • 主隊(duì)列: 以先進(jìn)先出的調(diào)度任務(wù),如果主線程上有任務(wù)在執(zhí)行星澳,主隊(duì)列不會(huì)調(diào)用任務(wù)

走進(jìn)NSOperation

  • NSOperation是一個(gè)抽象的類
  • 不能直接使用(方法沒(méi)有實(shí)現(xiàn))
  • 結(jié)束子類都具有共同的屬性和方法
  • NSOperation的子類
  • NSInvocationOperation
  • NSBlockOperation
  • 自定義operation
  • NSOperationQueue隊(duì)列
  • NSInvocationOperation

  • 新建一個(gè)NSInvocationOperation對(duì)象

    - (id)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;
  • 調(diào)用start方法開始執(zhí)行操作
    - (void) start;
    一旦執(zhí)行操作疚顷,就回到用start 的sel方法
注意

默認(rèn)情況下,調(diào)用start方法并不會(huì)開一條新線程執(zhí)行操作禁偎,而是在當(dāng)前線程同步執(zhí)行操作腿堤,只有將一個(gè)NSOperation放到NSOperationQueue中,才會(huì)異步執(zhí)行操作

接下來(lái)我們來(lái)測(cè)試一下
 - (void)viewDidLoad {
[super viewDidLoad];
//NSInvocationOperation操作
    //創(chuàng)建操作
  NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(diown) object:nil];
//創(chuàng)建隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//異步執(zhí)行
[queue addOperation:operation];
//同步執(zhí)行

 }
 -(void) diown{
NSLog(@"download --- %@",[NSThread currentThread]);
}
Snip20170409_7.png

可以看出如暖,在子線程中執(zhí)行的笆檀。如果沒(méi)有將NSOperation放到NSOperationQueue中,將會(huì)同步執(zhí)行装处,這里不做演示了

  • NSBlockOperation

  • 新建一個(gè) NSBlockOperation對(duì)象

    + (instancetype)blockOperationWithBlock:(void (^)(void))block;

*創(chuàng)建addExecutionBlock:方法添加更多操作
- (void)addExecutionBlock:(void (^)(void))block;

注意

只要NSBlockOperation封裝的操作 >1 就會(huì)執(zhí)行误债,異步操作

接下來(lái)我們來(lái)測(cè)試一下
  NSBlockOperation *operation = [[NSBlockOperation alloc]init];
[operation addExecutionBlock:^{
    NSLog(@"----下載圖片--1---%@",[NSThread currentThread]);
    
}];
[operation addExecutionBlock:^{
     NSLog(@"----下載圖片--2---%@",[NSThread currentThread]);
}];
[operation start];
Snip20170409_8.png
  • NSOperationQueue

  • NSOperationQueue的作用

NSOperation可以調(diào)用start方法來(lái)調(diào)用任務(wù),但是默認(rèn)是同步執(zhí)行妄迁。如果將NSOperation添加到NSOperationQueue的隊(duì)列中寝蹈,系統(tǒng)會(huì)自動(dòng),異步執(zhí)行

  • 添加操作到NSOperationQueue中
  - (void)addOperation:(NSOperation *)op;
  - (void)addOperationWithBlock:(void (^)(void))block ;

下面將演示這兩種不同的添加方式

  • 第一種
   NSOperationQueue *queue = [[NSOperationQueue alloc]init];
   NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(deom) object:nil];
  [op start];
  [queue addOperation:op];
 - (void) demo{
    NSLog(@"%@",[NSThread currentThread]);
 }
  • 第二種(創(chuàng)建全程隊(duì)列)--相比第一種登淘,這一種更為簡(jiǎn)便
 @interface ViewController ()
 //創(chuàng)建一個(gè)全程隊(duì)列
 @property (nonatomic, strong) NSOperationQueue *queue;
@end
//懶加載
- (NSOperationQueue *)queue{
if (_queue == nil) {
    _queue = [[NSOperationQueue alloc]init];
}
return _queue;
}
[self.queue addOperationWithBlock:^{
   
    NSLog(@"qqq %@",[NSThread currentThread]);

    NSLog(@"下載圖片");
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        NSLog(@"回到主線程");
        NSLog(@"%@",[NSThread currentThread]);
    }];
}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末箫老,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子黔州,更是在濱河造成了極大的恐慌耍鬓,老刑警劉巖阔籽,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異牲蜀,居然都是意外死亡笆制,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門涣达,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)在辆,“玉大人,你說(shuō)我怎么就攤上這事度苔〈衣ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵寇窑,是天一觀的道長(zhǎng)鸦概。 經(jīng)常有香客問(wèn)我,道長(zhǎng)甩骏,這世上最難降的妖魔是什么窗市? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮饮笛,結(jié)果婚禮上谨设,老公的妹妹穿的比我還像新娘。我一直安慰自己缎浇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布赴肚。 她就那樣靜靜地躺著素跺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪誉券。 梳的紋絲不亂的頭發(fā)上指厌,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音踊跟,去河邊找鬼踩验。 笑死,一個(gè)胖子當(dāng)著我的面吹牛商玫,可吹牛的內(nèi)容都是我干的箕憾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼拳昌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼袭异!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起炬藤,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤御铃,失蹤者是張志新(化名)和其女友劉穎碴里,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體上真,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咬腋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了睡互。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片根竿。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖湃缎,靈堂內(nèi)的尸體忽然破棺而出犀填,到底是詐尸還是另有隱情,我是刑警寧澤嗓违,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布九巡,位于F島的核電站,受9級(jí)特大地震影響蹂季,放射性物質(zhì)發(fā)生泄漏冕广。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一偿洁、第九天 我趴在偏房一處隱蔽的房頂上張望撒汉。 院中可真熱鬧,春花似錦涕滋、人聲如沸睬辐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)溯饵。三九已至,卻和暖如春锨用,著一層夾襖步出監(jiān)牢的瞬間丰刊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工增拥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啄巧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓掌栅,卻偏偏與公主長(zhǎng)得像秩仆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子渣玲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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