[iOS崩潰]App鍵盤彈出後進入後臺crash
問題
全域性替換NSArray
,NSMutableArray
,NSDictionary
,NSMutableDictionary
等集合的方法(比如objectAtIndex:,addObject:,setObject:forKey:
等等)去去獲取一些安全性時(避免新增nil
到陣列,或者nil
成為字典的key,value等情況)。
也會帶來一個問題,在ARC編譯環境下:
App彈出鍵盤後,進入後臺,會crash
堆疊在:
Thread : Crashed: com.apple.main-thread 0 libobjc.A.dylib 6806634868 objc_release + 20 1 libsystem_blocks.dylib 6813456656 _Block_release + 256 2 libobjc.A.dylib 6806640420 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 564 3 CoreFoundation 6529519172 _CFAutoreleasePoolPop + 28 4 UIKit 6605817924 _wrapRunLoopWithAutoreleasePoolHandler + 76 5 CoreFoundation 6530394704 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 6 CoreFoundation 6530382300 __CFRunLoopDoObservers + 360 7 CoreFoundation 6530383292 __CFRunLoopRun + 836 8 CoreFoundation 6529519780 CFRunLoopRunSpecific + 396 9 GraphicsServices 6682260900 GSEventRunModal + 168 10 UIKit 6606283712 UIApplicationMain + 1488 11 Spec 4297532060 main (main.m:15) 12 libdyld.dylib 6813280776 start + 4
開啟 Enable Zombie Objects
,可以看到崩潰時控制檯有輸出:
-[UIKeyboardLayoutStar release]: message sent to deallocated
這裡謹慎的懷疑是相關操作去release了NSArray
或者NSMutableArray
物件,但是在我們全域性替換那些方法時,是使用了ARC編譯的,是不需要手動release
的,可能這就造成了多次release
.
解決辦法
- 最直接簡單的是去掉這些集合的方法swizzle,但這樣會失去原來想要得到的特性
- 設定這些實現檔案的編譯選項為
-fno-objc-arc