问题
全局替换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