iOS-UITextField密文模式(secureTextEntry)下内存泄漏

keywords: Textfield/UITextField/secureTextEntry/内存泄漏

使用场景

近日,用户在使用我们的App的时候,发现一个问题,就是UITextfield在密文模式下,输入一定长度,出现卡死,闪退现象。刚开始以为是偶发性的,结果用户在重启手机,重新打开应用,问题依然在。而在我自己的手机上,却从来没有出现过这个问题,我的第一感觉可能是内存泄漏。因此,我就使用AnalyzeLeaks进行检测内存问题,发现并未出现内存泄漏提示。

原因分析

所以,当时有考虑可能是另外的原因:

  1. 手机应用系统版本
  2. 可能是三方库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-UITextField密文模式(secureTextEntry)下内存泄漏_第1张图片
UITextfieldConfiguration.png

iOS 10.0.1系统上运行,发现依然出现问题,其他版本暂未发现,如图:

iOS-UITextField密文模式(secureTextEntry)下内存泄漏_第2张图片
IMG_0106.PNG

由此可见,这个问题应该是 iOS10.0.1UITextField的一个 Bug,而不是三方库引起的。

问题所在

根据自己在storyboard修改的textfield的属性,一个一个的排查,发现当Secure Text Entry,设置为YESFont 的值大于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

解决方案

鉴于此,目前我能找到的解决方案:

  1. 升级手机系统。
  2. 密码模式下,Font 的值小于等于Min Font Size的值。
  3. 使用代码创建UITextField,不使用xibStoryboard

以上,才疏学浅,错误之处,还请批评指正。

你可能感兴趣的:(iOS-UITextField密文模式(secureTextEntry)下内存泄漏)