前言
今天发现一处只在iOS11上出现的崩溃.出现在下面这个代码片段.
self.testLabel.attributedText = @"";
self.testLabel.text = @"123";
[self.testLabel sizeToFit];
这样的写法当然不对,赋值attributedText的类型错误了.
不过为什么iOS11之前没有崩溃,在iOS11上崩了?
写了demo,用几种不同的写法,分别在10.3与11.0系统上试了一下.
iOS 10.3
- (void)addTestLabel
{
self.testLabel = [[UILabel alloc] init];
self.testLabel.attributedText = @"";
// self.testLabel.text = @"123";
[self.testLabel sizeToFit];
[self.view addSubview:self.testLabel];
}
此种写法会崩溃.
sizeToFit时,因为text无合法值,试图取attributedText的文本,调用了[attributedText string]接口.
- (void)addTestLabel
{
self.testLabel = [[TestLabel alloc] init];
self.testLabel.text = @"123";
self.testLabel.attributedText = @"";
[self.testLabel sizeToFit];
[self.view addSubview:self.testLabel];
}
此种写法会崩溃.
text设置合法值时,内部对attributedText做了对应赋值.外部再次设置attributedText触发了比对逻辑,对非法值调用了[attributedText string]接口.造成崩溃.
- (void)addTestLabel
{
self.testLabel = [[UILabel alloc] init];
self.testLabel.attributedText = @"";
self.testLabel.text = @"123";
[self.testLabel sizeToFit];
[self.view addSubview:self.testLabel];
}
此种写法不会崩溃.根据上面的经验看来,应该是路径上的逻辑没有调用到[attributedText string].
iOS 11
10.3上该崩溃的,在11上还是会崩.
所以直接调试10.3上不会崩溃的那段代码,结果确实是崩了.
从崩溃调用栈可以发现,iOS11在setText时,增加了与attributedText的比对逻辑,调用到[attributedText string]造成了崩溃.原因就在这里.
- (void)addTestLabel
{
self.testLabel = [[UILabel alloc] init];
self.testLabel.attributedText = @"";
self.testLabel.text = @"123";
[self.testLabel sizeToFit];
[self.view addSubview:self.testLabel];
}
130CDBF6-7A1A-4AF2-8EEC-0D92A751BE84.png
后记
这样的崩溃比较不应该,因为编译时就有类型转换错误的警告,因为没有及时解决,结果在新系统上踩了个大坑~
网友评论