keywords: Textfield/UITextField/secureTextEntry/内存泄漏
使用场景
近日,用户在使用我们的App
的时候,发现一个问题,就是UITextfield
在密文模式下,输入一定长度,出现卡死,闪退现象。刚开始以为是偶发性的,结果用户在重启手机,重新打开应用,问题依然在。而在我自己的手机上,却从来没有出现过这个问题,我的第一感觉可能是内存泄漏。因此,我就使用Analyze
和Leaks
进行检测内存问题,发现并未出现内存泄漏提示。
原因分析
所以,当时有考虑可能是另外的原因:
- 手机应用系统版本
- 可能是三方库Bug
有了问题,就要去解决问题,根据猜想,进行验证
1.手机系统版本问题
这个验证比较简单,得知用户手机系统版本为iOS 10.0.1
,于是找到一个相同版本的手机进行测试,发现当textfield
为密码模式的时候,真的会出现卡死,而且此时内存暴增,最终被系统kill
掉。而在其他系统版本iOS10
之前版本,和iOS10.3
都没问题(iOS 10.0.2
~iOS 10.2
版本未测试)。所以考虑极有可能是因为系统版本问题。
2.排除三方库Bug
为了排除三方库引起的Bug
,于是我就创建一个demo
,不引入任何三方库。
使用在storyboard
上拉一个UITextField
,设置如下图:
在iOS 10.0.1
系统上运行,发现依然出现问题,其他版本暂未发现,如图:
由此可见,这个问题应该是
iOS10.0.1
下UITextField
的一个Bug
,而不是三方库引起的。
问题所在
根据自己在storyboard
修改的textfield
的属性,一个一个的排查,发现当Secure Text Entry
,设置为YES
且Font
的值大于Min Font Size
的值的时候,就会出现这个问题。而当Secure Text Entry
设置为NO
时,却一切正常。由此推测是密码模式下引起的问题。
猜想
根据目前的情况来看,UITextField
在密码模式下,输入到一定长度(这里的一定长度,是根据textfield
的长度而言),才会触发内存泄漏,造成卡死。我们都知道,当textfield
输入的长度达到一定值的时候,输入的内容会自动变小,那么会不会是在这一瞬间引起的内存泄漏呢?带着猜想,我进行了下面的实验,在ViewController
中加入如下代码:
//在视图控制器的视图的layoutSubviews方法被调用之前调用。 子类可以根据需要实现。 默认是nop。
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
NSLog(@"%@",NSStringFromSelector(_cmd));
}
//在视图控制器的视图layoutSubviews方法被调用之后调用。 子类可以根据需要实现。 默认是nop
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
NSLog(@"%@",NSStringFromSelector(_cmd));
}
在明文模式下,当输入长度达到一定值时,输入内容字体变小时,发现果然会调用上面的两个方法,但只调用一次(除非再次变化),而密码模式下,卡死的一瞬间,一直重复调用上面的两个方法。这就证实了上面的猜想,在重新渲染的时候,发生了内存泄漏。
另外,还发现一个问题,纯代码创建UITextField
貌似,不会出现上面的问题。
总结
通过对比,发现这个问题,只是会出现在xib
或者storyboard
创建UITextField
时,纯代码创建不会出现这个问题,所以极有可能是在iOS10.0.1
版本下,xib
或者storyboard
的一个bug
。
解决方案
鉴于此,目前我能找到的解决方案:
- 升级手机系统。
- 密码模式下,
Font
的值小于等于Min Font Size
的值。 - 使用代码创建
UITextField
,不使用xib
或Storyboard
。
以上,才疏学浅,错误之处,还请批评指正。