你可以异步的执行网络任务使用NSURLConnection中的这个方法:
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler或者使用第三方框架比如 AFNetworking.
如果你在做任何大开销的操作(比如执行一个耗时的计算,或者读写磁盘)使用Grand Central Dispatch(GCD)或者 NSOperations 和 NSOperationQueues.
使用GCD的模板如下代码所示:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // switch to a background thread and perform your expensive operation dispatch_async(dispatch_get_main_queue(), ^{ // switch back to the main thread to update your UI });});这里为什么dispatch_async 嵌套在第一个的里面?这是因为任何UIKit相关的代码都必须在主线程上执行。
对NSOperation和GCD的详情感兴趣?看看Ray Wenderlich’s 教程,和 Soheil Azarpour’s How To Use NSOperations and NSOperationQueues 教程。
6)调整图像视图中的图像尺寸
如果你用UIImageView呈现app束中的图片时,确认图片和UIImageView的尺寸相同。缩放图片会非常的耗时,特别是当你的UIImageView被嵌入UIScrollView。
如果图片是从远程服务器上下载的,有时你没法控制图片尺寸,或者你不能在服务器上在下载之前缩放它。在这些情况下你可以在图片下载完成后手动缩放一次,最好是在后台进程中。然在UIImageView中使用调整尺寸之后的图片。
7)选择正确集合
学着怎么在手头工作中使用最合适的类或对象是写出高效代码的基本。当时用集合是(collections),这个说法特别对。
可喜的是在苹果开发者文档( )中有详细解释可用类之间的关系,还有解释各个类的适用情况。这个文档是每个使用集合的人的必读文档。
这是一个最常见的集合类型的快速简介:
Arrays:有序的值的列表,用index快速查找,通过值查找慢,insert/delete操作慢。
Dictionaries:存储键/值对.用index快速查找。
Sets: 无序的值列表。通过值快速查找,insert/delete快。
8)启用Gzip压缩
大量和持续增长的app依赖从远端服务器或者外部APIs获取的外部数据。某些时候你可能会开发一些需要下载XML,JSON,HTML或者其他文本格式的应用。
问题是移动设备不能保证网络环境,用户可能一分钟在边缘网络,下一分钟又是3G网络,无论什么情况下,你不想你的用户一直等待。
一个减少文件大小并加速下载的网络资源的方法是同时在你的服务器和客户端上使用GZIP压缩,对于文本数据这种有高比率压缩的数据来说非常有用。
好消息是iOS早已默认支持GZIP压缩,如果你是使用NSURLConnection或者建立在这之上的框架比如AFNetworking。更好的消息是一切云服务提供商像 Google App Engine早已发送压缩之后的响应数据。
这里有一篇文章great article about GZIP compression 介绍如何在你的Apache或IIS服务器上启用GZIP。
中级性能提升好的,当谈到优化你的代码时,你应该很自信你已经初级的方法已经完全掌握了。但有时候有的问题的解决方法并不是那么显而易见,它由你app的结构和代码决定,尽管如此,在正确的上下文中,它们可能是没有价值的。
9)重用和延迟加载视图
越多的视图就有越多的绘图操作,最终意味着更多的CPU和内存开销。这说得特别对如果你的app嵌入很多视图在UIScrollView时。
管理这个的技巧是去模拟UITableView 和 UICollectionView的行为:不要一次创建所有的子视图,而是在需要的时候创建,然后把他们假如重用队列中。
这样,你只需要在视图浮动时配置你的视图,避免昂贵的资源分配开销。
视图创建的时机问题也同样适用于你app的其他地方。试想当你点击一个button时呈现一个视图的情景。至少有两种方法:
1.屏幕第一次载入时创建视图并隐藏它。当你需要的时候,显示出来。
2.需要呈现的时候一次创建视图并显示它。
每种方法都有各自的优缺点
使用第一种方法,你消耗了更多内存因为从创建开始到它释放前你都保持了它的内存,然而,当你点击button的时候,你的app会表现得响应快速因为它只需要更改视图的可视化属性。
使用第二种方法会有相反的效果,在需要的时候创建视图,消耗更少的内存,但当button被点击时应用会表现得不那么响应快速。
10)缓存,缓存,缓存
在开发应用时的一个伟大的经验是”Cache what matters”–也就是说那些不大会改变但会平凡被访问的东西。
你能缓存些什么呢?缓存的候选项有远程服务器的响应,图片,已计算过的值(比如UITableView的行高)。
NSURLConnection 根据处理的Http头缓存资源到磁盘或者内存中,你甚至可以手动创建一个NSURLRequest值加载缓存过的值。
这里有一段很棒的代码,用在任何时候你需要针对一个不大会改变的图片创建一个NSURLRequest。
+ (NSMutableURLRequest *)imageRequestWithURL:(NSURL *)url { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // this will make sure the request always returns the cached image request.HTTPShouldHandleCookies = NO; request.HTTPShouldUsePipelining = YES; [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; return request;}如果想知道更多关于Http caching,NSURLCache,NSURLConnection等内容,请阅读the NSURLCache entry
注意,你可以通过NSURLConnection获取取一个URL请求,AFNetworking也可以。有了这个技巧这样你不用改变任何你的网络代码。
如果要缓存不牵扯到HTTP请求的其他东西,NSCache是很好的选择。
NSCache像NSDictionary,但是当系统需要回收内存的时候会自动的移除内容。
对HTTP Cache感兴趣并想学更多的内容?推荐阅读这篇文章best-practices document on HTTP caching
11)考虑绘图
在iOS中有很多方法可以制作拥有很棒外观的buttons,你可以是由全尺寸的图像,也可以使用调整尺寸之后的图像,或者你用CALayer,CoreGraphics,甚至OpenGL手动的它们。
当然,每种途径都有不同的复杂度级别和不同的性能,这篇文章非常值得一读,这是Apple UIKit团队成员Andy Matuschak发表的文章,里面对各种方法有一些非常棒的见解和对性能的权衡。