iOS9.2崩溃:NSTimer(PhotosUI) blockInvoke

来源:互联网 发布:剑灵忽雷捏脸数据 编辑:程序博客网 时间:2024/06/08 01:05

场景:iOS9.2调用MessageUI.framework的MFMessageComposeViewController发短信,调起发短信界面几秒后程序崩溃,必现。最后的堆栈为NSTimer(PhotosUI) blockInvoke。在iOS9.0以下的机器上一切正常。


解决思路:
1、排除系统的bug:新建一个工程,在iOS9.2的机器用同样的代码调起发短信界面,一切正常。初步怀疑是工程的代码跟系统的代码有冲突。
2、回到之前的工程,缩小范围:新建一个ViewController, 里面包含了之前发短信的代码,把AppDelegate不相关的代码都注释掉,把AppDelegate的window的rootController设置为新建的发短信的ViewController。跑一下,还是崩了。怀疑是工程里的+(void)load方法引起的,因为只为load方法在程序启动时会加载
3、把所有的+(void)load注释掉,再跑一下,没崩
4、逐一排查,最后发现有个load方法里调用用了个NSTimer的category, 这个category里时实现了个+(void)blockInvoke:(id)sender方法,到这里,问题已经很清晰了,这个方法跟崩溃日志里的方法一样。
5、还原注释掉的代码,把category里的blockInvoke方法名改一下, 程序运行正常。


问题分析:
1、iOS9后,PhotosUI.framework增加了NSTimer的category(秒有api),其中里面有个+(void)blockInvoke:(id)agr方法
2、MFMessageComposeViewController在运行时判断NSTimer有没有实现blockInvoke方法(刚好我的工程里实现了),有则直接调用PhotosUI.framework的NSTimer的blockInvoke方法,因为我的工程没有import PhotosUI.framework,所以系统找不到这个方法,崩了。这点是个人猜测,如有不当,望高人指正。


建议:
给系统的类加category时,函数名最好加上前缀或后缀,避免遇上同样的问题。
0 0