關(guān)于performSelector:afterDelay:的一個坑及思考

原文鏈接: https://kukumalucn.github.io/blog/2018/11/16/關(guān)于performSelector的一點注意/

前言

剛在群里看到這樣一段代碼垫释,很有意思:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"1");
        [self performSelector:@selector(test) withObject:nil afterDelay:0];
        NSLog(@"2");
    });
}
- (void)test
{
    NSLog(@"3");
}

這段代碼的執(zhí)行結(jié)果會是什么呢蒸绩?
是打印“1颈嚼、2”逃默,還是“1屿聋、3咧欣、2”凡泣,或者是“1枉疼、2皮假、3”?

內(nèi)容

1.問題探究

這其實是一道很有意思的面試題骂维,內(nèi)容涉及runloop這個知識點惹资。
答案是只打印:“1航闺、2”褪测。
原因群里的大神給了解答:

因為[self performSelector:@selector(test) withObject:nil afterDelay:.0]實際在runloop里面,是一個定時器来颤,但是因為在子線程汰扭,runloop是默認(rèn)沒有開啟的。

這除了涉及runloop福铅,還有多線程的問題萝毛,有興趣的可以深究。
其實我們只要仔細(xì)閱讀蘋果API的注釋滑黔,就能解釋這個問題:

performSelector:afterDelay:

想要執(zhí)行-test方法笆包,注釋里也提供了解決辦法:

[self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];

其實針對上述的邏輯,更簡單的是:

[self performSelector:@selector(test) withObject:nil];

2.引發(fā)的思考

2.1.不要懶

之所以要提上述的問題略荡,除了這個面試的“考點”庵佣,其實在平時的開發(fā)過程中也要注意自己代碼的嚴(yán)謹(jǐn)性。
我發(fā)現(xiàn)自己在閱讀別人的代碼時汛兜,就見過同樣的寫法巴粪,其實甚至那些比較有名的三方庫,例如“YYText”中粥谬,也有類似的代碼存在:

[self performSelector:@selector(test) withObject:nil afterDelay:0];

寫這段代碼的人只是為了通過selector來立刻執(zhí)行某一方法肛根,delay并不是他們的需求,為什么還要“多此一舉”呢漏策?
這里一大部分原因派哲,很可能還是因為我們被xcode的自動提示給“慣壞了”:

perform自動提示

畢竟當(dāng)你寫代碼時,羅列的一堆提示掺喻,只是按照API相似度排列出來的芭届,很多人看到了自己需要的就直接回車了,不需要delay感耙,直接寫0褂乍,就行了,反正“都一樣”……
其實這是一個誤區(qū)即硼,看起來很相似的API树叽,實則并不一樣,而且很不一樣:

  • 我們常用的這個perform谦絮,是NSObject.h這個頭文件下的方法:
perform-NSObject.h
  • 可以delay的题诵,是NSRunLoop.h下的方法:
perform-NSRunLoop.h
  • 而之前提到的回調(diào)主線程的洁仗,是NSThread.h里的方法:
perform-NSThread.h

雖然他們都是NSObject的方法或者是分類補充方法,但實際上性锭,是隸屬于不同的模塊的赠潦。

2.2.更深刻的原因

但是“YYText”的作者應(yīng)該是不會犯這種低級錯誤的,那就應(yīng)該還有更深刻的原因了:

performSelector may cause a leak

我們很多人應(yīng)該總是會被上述的警告所困擾草冈,大多數(shù)人的解決方式她奥,就是利用類似相面的方式去屏蔽警告,這種做法雖然簡單怎棱,但實際是有風(fēng)險的:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
//code
#pragma clang diagnostic pop

其實除了利用IMP或者NSInvocation那種比較“高端”的方式哩俭,更多的情況下,在方法沒有返回值時拳恋,或者我們不需要返回值時凡资,我們可以用:

[self performSelector:@selector(test) withObject:nil afterDelay:0];

這種方式去避免警告的,看上面的那三個對比你就會發(fā)現(xiàn)谬运,后兩類API隙赁,同樣是performSelector,卻沒有返回值梆暖,這其實也是有官方注釋的依據(jù)的:

PerformSelector官方注釋

但其實你也要注意到了伞访,官方的建議還是很嚴(yán)謹(jǐn)?shù)模怯?code>performSelectorOnMainThread轰驳,而不是delay0的方式厚掷,至于原因,我們又回到了文章一開頭的討論了级解。

總結(jié)

通過上面看似無意義的探究冒黑,我們還是可以得到很深刻的教訓(xùn)的:“蘋果霸霸”還是很嚴(yán)謹(jǐn)?shù)模嗫碅PI的注釋蠕趁,總是沒錯的薛闪。


本文作者: 霖溦
原文鏈接: https://kukumalucn.github.io/blog/2018/11/16/關(guān)于performSelector的一點注意/
本文鏈接: 關(guān)于performSelector:afterDelay:的一個坑及思考
版權(quán)聲明: 本博客所有文章除特別聲明外辛馆,均采用 CC BY-NC-ND 4.0 許可協(xié)議俺陋。轉(zhuǎn)載請注明出處!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昙篙,一起剝皮案震驚了整個濱河市腊状,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苔可,老刑警劉巖缴挖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異焚辅,居然都是意外死亡映屋,警方通過查閱死者的電腦和手機苟鸯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棚点,“玉大人早处,你說我怎么就攤上這事√蔽觯” “怎么了砌梆?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贬循。 經(jīng)常有香客問我咸包,道長,這世上最難降的妖魔是什么杖虾? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任烂瘫,我火速辦了婚禮,結(jié)果婚禮上亏掀,老公的妹妹穿的比我還像新娘忱反。我一直安慰自己,他們只是感情好滤愕,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布温算。 她就那樣靜靜地躺著,像睡著了一般间影。 火紅的嫁衣襯著肌膚如雪仑扑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天仆抵,我揣著相機與錄音籽前,去河邊找鬼。 笑死付燥,一個胖子當(dāng)著我的面吹牛宣谈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播键科,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼闻丑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了勋颖?” 一聲冷哼從身側(cè)響起嗦嗡,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饭玲,沒想到半個月后侥祭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年矮冬,在試婚紗的時候發(fā)現(xiàn)自己被綠了谈宛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡胎署,死狀恐怖入挣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情硝拧,我是刑警寧澤径筏,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站障陶,受9級特大地震影響滋恬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抱究,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一恢氯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鼓寺,春花似錦勋拟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苦银,卻和暖如春啸胧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背幔虏。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工纺念, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人想括。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓陷谱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瑟蜈。 傳聞我的和親對象是個殘疾皇子烟逊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

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