问题:
-
突然发现问题:测试说,我们项目在 iOS 8 下,点击某个 UITextField 会有闪退,经过测试发现确实是的,但是在 iOS 9下和 iOS 7下是好的。而且iOS8也不是一定会出现。
-
找必现路径:然后就找必现路径,发现是这样的第一次从一个页面跳转到编辑控制器(登录Login页面)没有什么问题,但当返回后再次进入编辑控制器点击UITextField就出现了所说的崩溃了。
-
排查问题:所以呢,找到必现路径后,就开始排查问题了,这边的方法很常规,就是通过打开Enable Zombie Objects,
> Enable Zombie Objects.png
然后再进运行,让崩溃重现,僵尸断点发现错误:-[UITextField textInputView]: message sent to deallocated instance 0x159fc800,测试环境是真机(iPhone5,iOS8.4)。 -
分析产生原因:我又试着在iOS10的系统上测试,发现并没有什么问题,可能iOS8和10的一些内存处理策略不一样。
-
尝试解决:一开始你可能会各种分析内存问题,硬是觉的写的没问题啊,后来将其抽离出来,发现还是一直崩。
-
别人的解决方法:是自己写的 Category中可能是某个监听没有移除掉导致的。可以参见:UITextField textInputView message sent to deallocated instance
-
自己的解决:参照别人的解决检查是否Category中有通知,有的话,则删掉,结果还是会崩溃。最后在连-dealloc方法也整个删掉之后发现不会有问题了,很奇怪。终点是这个category我再这个文件中根本没去引用,很奇怪吧。但是解决了就好。类似的有上面中的一句
UITextField textInputView message sent to deallocated instance
After I removed dealloc method crashes disappeared. Therefore I decided to find new way to implement autosuggestion feature.
The interesting thing is that I didn't import header file in code anywhere, but crashes occurred.
其他:
解决LLDB模式下出现message sent to deallocated instance错误
在Xcode的以前版本中,我们可以在Xcode的Console View中使用info malloc-history 0x6d564f0来查看调用堆栈来查看崩溃发生的地方。
在新的Xcode中,调试器默认使用的LLDB,那么怎么在LLDB状态下定位由于内存操作不当引起的Crash呢?
打开“活动监视器”,在进程列表中找到测试APP对应的进程号PID(Xcode启用调试后会在进程列表中找到对应APP的进程)
image
现在我们得到两个主要的信息:
APP进程ID:1087
崩溃地址:0x7f7f7523ff10
打开“终端”,输入以下命令:
sudo malloc_history 1087 0x7f7f7523ff10
得到错误日志,这样就能定位到最后调用的那行代码
image
downLoadBtns是我们自定义的一个方法,在这个方法内部对新构建的UIButton做释放,它就是引起崩溃的元凶。
[btn release];
附上其他人遇到一样问题的经历:
别人1:UITextField textInputView: message sent to deallocated instance
别人2:关于iOS8上使用UITextView内存泄漏的一个坑:-[UITextView textInputView]: message sent to deallocated instance
网友评论