《招一個(gè)靠譜的iOS》41-45

本人參考GitHub《招聘一個(gè)靠譜的iOS》面試題參考答案(下)
41. 使用系統(tǒng)的某些block api(如UIView的block版本寫動(dòng)畫時(shí)),是否也考慮引用循環(huán)問題?
42. GCD的隊(duì)列(dispatch_queue_t)分哪兩種類型?
43. 如何用GCD同步若干個(gè)異步調(diào)用?(如根據(jù)若干個(gè)url異步加載多張圖片,然后在都下載完成后合成一張整圖)
44. dispatch_barrier_async的作用是什么?
45. 蘋果為什么要廢棄dispatch_get_current_queue

41. 使用系統(tǒng)的某些block api(如UIView的block版本寫動(dòng)畫時(shí)),是否也考慮引用循環(huán)問題?

系統(tǒng)的某些block api中,UIView的block版本寫動(dòng)畫時(shí)不需要考慮循環(huán)引用。
但也有一些API需要考慮:
循環(huán)引用指雙向的強(qiáng)引用,所以單向的強(qiáng)引用(block強(qiáng)引用self)沒有問題,比如:

[UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded]; } ];
[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.someProperty = xyz; }];
[[NSNotificationCenter defaultCenter] addObserverForName:@"someNotification" 
                                                  object:nil 
                                                   queue:[NSOperationQueue mainQueue]
                                              usingBlock:^(NSNotification * notification) {
                                                   self.someProperty = xyz; }]; 

這些情況不需要考慮“引用循環(huán)”。
但如果使用一些參數(shù)中可能含有ivar(實(shí)例變量)的系統(tǒng)api,如GCD、NSNotificationCenter就要小心點(diǎn),比如:GCD內(nèi)部如果引用了self,而且GCD的其他參數(shù)是ivar,則要考慮循環(huán)引用:

__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
    __typeof__(self) strongSelf = weakSelf;
    [strongSelf doSomething];
    [strongSelf doSomethingElse];
}
);

類似的:

__weak __typeof __(self) weakSelf = self;
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"testKey"
                                                              object:nil
                                                               queue:nil
                                                          usingBlock:^(NSNotification *note){
    __typeof __(self) strongSelf = weakSelf;
    [strongSelf dismissModalViewControllerAnimated:YES];
}];

self-->_observer-->block-->self顯然這也是一個(gè)循環(huán)引用。

42. GCD的隊(duì)列(dispatch_queue_t)分哪兩種類型?

  1. 串行隊(duì)列Serial Dispatch Queue
  2. 并行隊(duì)列Concurrent Dispatch Queue

43. 如何用GCD同步若干個(gè)異步調(diào)用?(如根據(jù)若干個(gè)URL異步加載多張圖片,然后在都下載完成后合成一張整圖)

使用Dispatch Group追加block到Global Group Queue,這些block如果全部執(zhí)行完畢,就會(huì)執(zhí)行Main Dispatch Queue中的結(jié)束處理的block。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE)PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{/*加載圖片1 */});
dispatch_group_async(group, queue, ^{/*加載圖片2 */});
dispatch_group_async(group, queue, ^{/*加載圖片3 */});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
      // 合并圖片
});

44. dispatch_barrier_async的作用是什么?

在并行隊(duì)列中,為了保持某些任務(wù)的順序,需要等待一些任務(wù)完成后才能繼續(xù)進(jìn)行,使用barrier來等待之前任務(wù)完成,避免數(shù)據(jù)競爭等問題。dispatch_barrier_async函數(shù)會(huì)等待追加到Concurrent Dispatch Queue并行隊(duì)列中的操作全部執(zhí)行完之后,然后再執(zhí)行dispatch_barrier_async函數(shù)追加的處理,等dispatch_barrier_async追加的處理執(zhí)行結(jié)束之后,Concurrent Dispatch Queue才恢復(fù)之前的動(dòng)作繼續(xù)執(zhí)行。
打個(gè)比方:比如公司周末跟團(tuán)旅游,告訴休息站上,司機(jī)說:大家都去上廁所,速戰(zhàn)速?zèng)Q,上完廁所就上高速。超大的公共廁所,大家同時(shí)去,程序猿很快就結(jié)束了,但程序媛就可能慢一些,即使第一個(gè)人回來,司機(jī)也不會(huì)出發(fā),司機(jī)要等待所有人都回來后,才能出發(fā)。dispatch_barrier_async函數(shù)追加的內(nèi)容就如同“上完廁所就上高速”這個(gè)動(dòng)作。
注意:使用dispatch_barrier_async函數(shù)只能搭配自定義并行隊(duì)列dispatch_queue_t使用,不能使用dispatch_get_global_queue,否則dispatch_barrier_async的作用和dispatch_async的作用一模一樣。

45. 蘋果為什么要廢棄dispatch_get_current_queue?

dispatch_get_current_queue容易造成死鎖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容