产生场景
通过继承UITextField自定了一个textfield,在iOS11以下可以正常使用,在iOS11使用的时候无法释放,不走- (void)dealloc 方法。通过Facebook的开源库FBRetainCycleDetector检测得到相应报告 如图一 图二。尝试过切换第一响应者和在父类中置textfield为nil,未成功。
产生原因
根据FBRetainCycleDetector可以大致看到猜到原因。UITextField有一个名为_textContentView的私有变量,这个私有变量有一个名为_provider的私有变量,这个_provider就是UITextField自己。这些私有变量都是被强引用的,因此在使用当中引起了循环引用。
解决方案
在该UITextField子类当中置_provider为nil。
- (void)didMoveToWindow
{
[super didMoveToWindow];
if (@available(iOS 11.2, *)) {
NSString *keyPath = @"textContentView.provider";
@try {
if (self.window) {
id provider = [self valueForKeyPath:keyPath];
if (!provider && self) {
[self setValue:self forKeyPath:keyPath];
}
} else {
[self setValue:nil forKeyPath:keyPath];
}
} @catch (NSException *exception) {
NSLog(@"%@", exception);
}
}
}
疑惑
iOS11为什么多一个provider私有成员变量,有什么作用,置为nil后有什么影响。