原文引用https://www.dazhuanlan.com/2019/08/26/5d62f6f027452/
/
从25 iOS App Performance Tips & Tricks翻译了部分提高app性能的技巧
中阶性能提升建议
9)复用和延迟加载
更多的视图意味着更多的绘制,这些最终意味着更多CPU和内存的开销。在通过UIScrollView展示很多视图时开销尤为明显。
因此,效仿UITableView和UICollectionView的思路,并不在一开始就创建所有视图,在需要的展示时候创建,并不显示的视图加入重用队里里。
通过这个方法我们显示新的视图时,只需要设置复用视图的属性,而避免了新建视图会引起的内存分配和初始化开销。
延迟加载的方法也可以用在其它情景。比如你需要通过点击按钮来展示一个视图,至少有两种实现形式:
- 在页面加载时创建并隐藏。需要时再显示出来。
- 直到点击按钮时才创建并显示。
这两种方法各有优缺点。第一种会长期占用内存空间,但是显示速度快。第二种刚好相反,不占空间但展示慢。具体采用哪种方式可以根据应用场景权衡。
10)缓存、缓存、缓存
一项普遍的的开发经验就是”缓存那些有必要缓存的东西”,即缓存那些不太会改变但是经常访问的数据。
具体可以缓存什么数据呢?比如服务器返回的数据,图片,甚至是计算后的值如UITableView的高度。
NSURLConnection已经根据HTTP请求头将资源存储到本地或内存中,你甚至可以人为设置NSURLRequest,让它只访问缓存的数据。
+ (NSMutableURLRequest *)imageRequestWithURL:(NSURL *)url {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // 这一选项会总是返回缓存的图片
request.HTTPShouldHandleCookies = NO;
request.HTTPShouldUsePipelining = YES;
[request addValue:@"image/*" forHTTPHeaderField:@"Accept"];
return request;
}
注意,你可以用NSURLConnection来进行URL请求,同样AFNetworking也可以。而且你不需要改变什么代码,因为它已经做得足够好。
如果你想了解更多关于HTTP缓存的知识,可以涉猎NSURLCache,NSURLConnection等相关知识,确保浏览了NSHipster网站上的这篇文章
如果你需要缓存不包含在HTTp请求中的数据,可以涉猎NSCache。NSCache和NSDictionary表现的很像,但是当系统需要更多空间资源时,它会被释放。Matt Thompson在NSHipster写了一篇很赞的文章可以阅读一下。
想要了解更多关于HTTP缓存的知识,推荐阅读Google的《 best-practices document on HTTP caching》。
11)考虑图形绘制
在iOS上有好几种方式可以实现漂亮的按钮。可以用全尺寸图片或可伸缩图片显示,再复杂点用CALayer,CoreGraphics甚至OpenGL来绘制。
这些效果的实现难度不同和当然性能也不同。有篇很棒的文章讲述iOS图形性能,很值得阅读。同时,苹果UIKit项目组的成员Andy Matuschak也针对这篇文章给出了深度的分析。
简而言之,使用图片是最快的,因为iOS省去了绘制图形的过程,直接将图片渲染到屏幕上。问题是你需要把所有的图片都放入bundle中,这增加了app的大小。所以使用可伸缩尺寸的图片来绘制按钮更好。iOS会帮你绘制那些重复的纹理。你也不用针对不同尺寸的元素(如按钮)生成不同的图片。
毕竟通过使用图片你可能会丧失图片微调的能力,当你需要对不同的场景对视图进行微调时,你依旧需要处理大量的图片,不能通过代码直接调整。这会是一个繁复的过程。
所以,在绘制性能和app大小上,你需要根据自己的需要进行折中。
高阶性能提升建议
22)提升进程启动速度
启动速度提升主要的核心在于避免阻塞主线程,异步处理繁重的任务,如网络请求、数据库操作或者解析数据。同时避免加载臃肿的XIB文档,XIB文档在主线程中加载,而storyboard不存在这个问题,有需要可以尽可能考虑storyboard。
23)使用Autorelease Pool
NSAutoreleasePool是用于释放对象的进程块。通常情况下由UIKit来调用。但是在有些场景中我们需要认为创建。
比如当你需要创建大量的临时对象时,内存使用量会因此飙升直到未来某时刻统一被UIKit释放。这就意味这些临时对象存在的时间比需要的时间长。所以我们需要手动及时地释放这些对象。
NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
@autoreleasepool {
NSError *error;
NSString *fileContents = [NSString stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding error:&error];
/* 处理数据或其它创建操作 */
}
}
24)选择性图片缓存
有两种常见的方式来加载app bundle中的图片。imageNamed
和imageWithContentsOfFile
。前者会先从系统缓存中寻找图片对象,如果没有则创建新的对象并缓存,适用于频繁使用的图片。后者没有缓存机制,适合不常使用的资源消耗较大的图片。
25)避免使用Date Formatter
在大量需要用到NSDateFormatter的情景下,可使用类似单例的形式初始化,重复使用一个NSDateFormatter对象。如果想要进一步提高速度,则可以采用C语言的方式。还有一种更好的方式就是使用Unix timestamps。一个标示时间的浮点数,纪录了自1970年1月一日到现在的时间间隔。通过NSDate很容易的实现时间转换。
- (NSDate*)dateFromUnixTimestamp:(NSTimeInterval)timestamp {
return [NSDate dateWithTimeIntervalSince1970:timestamp];
}
原文地址:https://www.cnblogs.com/petewell/p/11410421.html