介绍
记录、总结开发遇到一些问题,大家一起交流学习。
这次带来,对直播APP性能优化的总结,以QA的形式总结。
欢迎关注文集-直播Live
实现方式
1、Q:礼物动画如何实现?
A:礼物分小礼物动画和豪华礼物处理;
序列帧+GCD+layer动画+UIView的Block动画组合使用;
2、Q:定时器采用CADisplayLink还是NSTimer?
A:都可以。重点在于添加到的mode,个人采用的是添加到
NSRunLoopCommonModes
的CADisplayLink。
3、Q:CADisplayLink对应的屏幕刷新和Xcode的FPS是什么关系?
A:CADisplayLink对应的是屏幕刷新帧率,一般60FPS;
xcode的FPS是真实显示的帧率,只要一帧处理的时间超过16ms,显示帧率就不会为60FPS;
4、Q:小礼物的连击效果如何实现?
A:逻辑上,礼物连击可以看成多个桶排成的队列,礼物赠送者id+礼物类型相同的放在一个桶内。连击过程中,可以不断往桶里放礼物。如果连击完成,桶里没有礼物,开始放下一个桶的礼物。
实现上,给礼物数字放大缩小动画设置delegate,在stop回调的时候进行上述的逻辑判断即可。
5、Q:小礼物的连击数字是[0-9]的文字图片组成的,每次显示都需要拼接图片,如何优化?
A:用富文本的格式,同时图片用imageNamed的形式加载;如果内存不紧张,可以把富文本根据num缓存,避免多次拼接;
NSMutableAttributedString * mutableAttributedString = [[NSMutableAttributedString alloc] initWithString:sendGiftNumStr];
UIImage *giftNumIcon = [UIImage imageNamed:imageName];
NSTextAttachment *giftXAttachment = [[NSTextAttachment alloc] init];
giftXAttachment.image = giftNumIcon;
NSAttributedString *giftXAttributedString = [NSAttributedString attributedStringWithAttachment:giftXAttachment];
[mutableAttributedString replaceCharactersInRange:NSMakeRange(0, 1) withAttributedString:giftXAttributedString];
图片加载
1、Q:加载图片iPhone4+iOS7,加载图片,提示:
Could not load the "gift_plane" image referenced from a nib in the bundle with identifier
Unable to create unsliced image from csi bitmap data
Unsupported pixel format in CSI
A:把Images.xcassets里面的jpg相关的图片换成png。
The issue is that iOS 7 apps cannot have JPEG images in the CAR file. actool should have copied the JPEG as a loose image into your app's folder. To work around this issue, you should either convert the image to a PNG or include the JPEG as a resource outside of the asset catalog.
2、Q:直接以引用方式导入的图片,pathForRes查找图片的路径?
A:方式1
[UIImage imageNamed:imagePath]
imagePath为图片的相对路径;
方式2:
imagePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:imageName];
[UIImage imageWithContentsOfFile:imagePath];
imagePath为图片的相对路径,而且必须附带.png的后缀;
3、Q:imageWithContentsOfFile加载的图片没有缓存,重复使用的时候会加载多次,是否可以用NSMutableArray存储起来?
A:不行。可以使用NSCache,步骤如下:
1、加载cache中的图片; 如果有则返回,没有到步骤2;
2、加载本地的缓存文件,如果有则返回,没有到步骤3;
3、从网络下载图片,到步骤4;
4、存入本地的缓存文件,到步骤5;
5、放入cache,返回图片;
如果不需要网络下载图片,可以去除3、4步骤,同时可以同步返回;
如果使用array存储图片,会一直持有引用;NSCache会在内存不足时主动释放,故而加载的时候需先判断是否有缓存文件;
4、Q:使用序列帧的时候,需要加载很多次图片?
A:可以把多张图片放到一张图片,加载后通过
-CGImageCreateWithImageInRect
切割出多张图片;
内存优化
1、Q:直播的时候送出一个豪华礼物,为何内存会增加20M?
A:一个豪华礼物占用的内存包括图片内存+Animation(动画)内存;
2、Q:美术给出的资源总共加起来才几百k的大小,为何加载到内存会增加这么多?
A:先查看加载方式,
+imageNamed:
的方式会添加缓存,但使用完不释放;+imageWithContentsOfFile:
的方式不会添加缓存,重复使用会占用多次内存,但使用完会回收;
其次,通过instruments工具查看,imageio_png_data占用内存过多;查看ipa包的图片资源,发现有三张图片分别为(3910528 + 1761437 + 9104388),大小占用450k;简单计算下,(3910528 + 1761437 + 9104388) * 4 = 25M,确定为三张图片过大;
3、Q:如何计算出来的图片大小?
A:图片的颜色空间为RGBA,那么加载到内存的大小=widthheight4bytes;
性能检测工具
1、Q:instruments录制按钮显示unable to find a service to record with
A:检查xcode版本能支持的最大手机版本,没问题的话重启手机和xcode,重新连接。
2、Q:instruments的Anonymous VM(匿名虚拟内存)是什么?
A:匿名虚拟内存是系统为程序预留的、可能会立即被重复使用的一部分可用内存。
3、Q:instruments检查发现除了礼物送频繁后,聊天的UITableView消耗的时间也很长,如何优化?
A:从cell高度计算、图片加载、布局layout开始优化;
a.cell高度不会变,可以缓存;
b.图片加载可以用imageNamed或者cache实现;
c.尽量避免使用autolayout;
d.控制每帧刷新数量;
e.删除过多的历史消息;
总结
优化通过压力测试+instruments工具检测出瓶颈,同时检测代码逻辑实现。这些QA都是优化过程中的一些问题和解决方案,如果有建议和疑问欢迎交流。
网友评论
1.如何控制每帧刷新的数量
2.我发现tableview消耗cpu的一个操作是scrolltobottom,因为每收到一条消息的时候,默认是reloadData 再 滚动到底部。