之前看一位苹果工程师的博客,里面有提到UILabel显示文案的时候会有很大的内存消耗,建议当前隐藏或者不使用的UILabel在不影响功能的前提下,将label的文本设置为nil。
内存消耗对于一个合格的iOS开发者来说是需要特别注意的点,碰到这种问题时一定要一探究竟,耳听为虚、眼见为实,立即上代码一探究竟。
实例化一个屏幕大小的UILabel,不设置任何文案,只单纯设个一个背景色,代码如下:
UILabel *lb = [UILabel new];
lb.textColor = [UIColor redColor];
lb.backgroundColor = [UIColor yellowColor];
lb.frame = CGRectMake(0,0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
lb.numberOfLines = 0;
[self.view addSubview:lb];
在没有任何文案的情况,来看一下内存消耗,如图:
实验一
然后给label设置足够多的文案
NSString *string = @"测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据测试数据";
lb.text = string;
此时的内存消耗:
由此可见,设置了文本的UILabel相对于空文本的UILabel的内存占用多了8M多。
实验二
然后给label设置足够多的多色富文本
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
for (int i = 0; i<string.length; i++) {
if (i%2==0 && i < string.length) {
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(i, 1)];
}
}
lb.attributedText = attributedString;
此时的内存消耗
由此可见,设置了富文本的UILabel相对于设置了文本的UILabel的内存占用多了1M多。
实验三
讲UILabel隐藏,再次运行观察内存
lb.hidden = YES;
内存仍然被占用,并没有明显的内存释放
原理分析
UILabel显示正常单色文案,UILabel将选择kCAContentsFormatGray8Uint的calayercontents格式(每像素1字节),此时最多消耗width * height * contentsScale ^ 2 *(每像素1字节)字节;
UILabel显示多色富文本时,UILabel将选择kCAContentsFormatRGBA8Uint(每像素4字节),此时最多消耗4倍的:width * height * contentsScale ^ 2 *(每像素4字节) 。
例如,在iPhone 11 Pro Max上,大小为414 * 100 points的lable最多可消耗:
- 414 * 100 * 3 ^ 2 * 1 = 372.6kB(单色文案)
- 414 * 100 * 3 ^ 2 * 4 =〜1.49MB(多色富文本文案)
由此可见,UILabe的内存消耗真的是不容小视的存在。
建议
综上分析UILabel的内存消耗绝对不容小视,尤其当UILabel显示多色文案富文本时,更是内存炸弹一般的存在,况且每个项目中UILabel的个数一般会很多,这样积少成多的内存消耗对于一个APP来说是一笔不小的开销。因此在日常的开发中,必须将UILabel重视起来。
1、在UILabel隐藏的时候将UILabel的文本设置成nil。
2、在UITableView / UICollectionView cell中存在UILabel时,当cell出发didEndDisplayingCell时,将cell中UILabel的文本设置成nil。
参考链接:https://www.fadel.io/blog/posts/ios-performance-tips-you-probably-didnt-know/