ARC下強制retain

遷移老文章到掘金框架

引子

主要是因爲上一篇文章callselector引發的函數

若是斷點調試,整個call_selector的過程徹底走完都不會有事,可是一旦放開斷點,完全走完就崩潰。 爲啥呢?由於在使用invocation的時候 invoke的過程當中,若是對象在invoke內被建立初始化了,invoke結束後,在下一個autorelease的時間點就會產生zombie的crash,send release to a dealloc objectui

爲何會這樣,簡單的說下個人理解不細說吧,invoke和直接函數調用不太同樣,若是發生了alloc對象,那麼這個對象系統會額外多一次autorelease,因此,不會馬上崩潰,但當autoreleasepool釋放的時候,就會發生過分release。spa

invoke函數會致使ARC下額外的一次autoRelease,因此在自動釋放池釋放後就會多一次release,致使zombie指針

有點挫的解決辦法

就是我在上一篇callselector提到的調試

由於多了個release,那我再arc下不能強制retain,那我就add到一個字典裏,讓他被arc retain一下code

因而問題是解決了,可是也產生了一個一直存在的static字典,而且這個字典裏,這個key所對應的數據已經野指針,千萬不能操做,一旦操做就野指針crash,你對字典進行removeall,也會野指針crash對象

威武的思路

@無邊的翅膀 在個人簡書下留言內存

針對這個,我想給出一個建議。在ARC下修改一個對象的引用計數,可使用CoreFoundation框架的API,CFRetain和 CFRelease 函數rem

這個思路靠譜啊,因而動手試驗

const void* cfobj = CFBridgingRetain(obj);
CFRetain(cfobj);
CFBridgingRelease(cfobj);
複製代碼
  • 將對象的內存管理控制移交給CF
  • CFRetain
  • 將對象的內存管理移交回ARC(讓使用者無感知)

我其實對CF這塊並非很熟悉。初步跑通了一下,感受沒啥問題

而後@無邊的翅膀 給出了修改意見

不須要這麼複雜,一行代碼就好,CFRetain((__bridge CFTypeRef)(obj));

簡直太讚了!

ARC下的MRC

若是實在無可奈何必定得在ARC下進行MRC操做的話。。不管是releaseretain這樣也能夠有辦法了,可是

慎用啊

相關文章
相關標籤/搜索