iOS Quick Tip: 5 Tips to Increase App Performance
Bart Jacobs on Jul 19th 2013 with 2 comments
Tutorial Details
- Difficulty: Intermediate
- Completion Time: 30 Minutes
- Technology: iOS SDK
Even though the iPhone 5 and the iPad 4 ship with a powerful A6(X) processor and a lot more RAM than the original iPhone, this doesn’t mean that iOS applications are by definition fast and performant. In this quick tip, I will give you five tips to improve application performance.
尽管iPhone5和iPad4装载了一个强力的A6(X)处理器,拥有着比以前iPhone更多的内存,你以为你的程序就能比以前跑得快了?代码写得烂一样跑不快哦.我会给你5点提示来让你的应用程序表现得更好.
1. Caching
If an iOS application fetches a remote resource, it is important that it doesn’t fetch that same resources every time it needs to access it. If you plan to develop a Twitter client for iOS, for example, then the client shouldn’t be downloading the same avatar every time it needs to display it. Caching the avatar will significantly improve application performance.
如果一款应用依靠着网络上的资源来运作,那么,你总不能每次都不停的获取(服务器上)相同的资源吧.如果你计划研发一款Twitter的客户端软件,那么,这个客户端就不应该每次都下载相同的数据来显示它.缓存这段数据就是个非常有效的方法.
What is caching? The basic idea of caching is simple. When the application fetches a remote resource for the first time, it stores a copy of that resource on disk for later use. If that same resource is needed later, the application can load it from disk instead of fetching it remotely. The added benefit is that the resource is also available when the device is not connected to the web. The complex aspect of caching is how to store the resource, when to store it, and, most importantly, when to refresh it.
什么是缓存?原理是很简单的.但应用软件第一次获取服务器上的资源时,它就存储了一份拷贝在闪存上方便以后的使用.以后的某段事件你又需要用到那段数据,应用软件就直接从闪存中读取出来而不用再次从服务器中获取.另外一点的好处呢,就是即使你的应用连接不上网络获取不了资源数据,你本地上还是有得.恩,难点呢,就是怎么去缓存数据,什么时候去缓存它,最重要的是,什么时候刷新它.
Olivier Poitrey has developed a small library named SDWebImage that is aimed at caching images. It provides a category on UIImageView
much like AFNetworking does. The key difference is that SDWebImage caches the images it downloads. Images are downloaded in the background and each images is decompressed, resulting in faster load times. The library leverages Grand Central Dispatch to keep the main thread responsive. If your application works with remote images, then you should take a look at this gem.
Olivier Poitrey 已经搞出了一个很小的库,名叫SDWebImage,专门用来缓存图片的.他给UIImageView提供了一个类目就像AFNetworking所做的那样.但他们有着一个核心的不同点:SDWebImage能缓存已经下载过的图片.图片在后台下载完之后再进行解压,目的是为了应用程序快速的加载.这个库会促使GCD(多核编程)保持与主线程良好的响应,如果你的应用程序需要经常加载服务器的图片资源,也许你应该瞧瞧这个不错的库.
2. Do Not Block the Main Thread
One of the most important lessons to learn when developing for the iOS platform is to never block the main thread. If you block the main thread with a long running operation, such as downloading images or other resources, your application will become unresponsive as long as the operation isn’t completed. Make it a habit to move long running tasks to a background thread. Even if you only need a handful of bytes, if the device’s connection to the web is slow, the operation will still block the main thread.
请记住一点,永远不要阻塞主线程.如果你执行了一段运行时很长的代码而阻塞了主线程,例如下载图片资源或者其他资源,你的应用程序将会变得反应迟钝直到你的那段代码执行完毕了.把那段代码转移到后台的线程去吧.即使是你仅仅想获取一点点字节数的资源,如果连接那个网站很慢呢?这个代码一样也会阻塞主线程的.
Writing safe multithreaded code has become a lot easier with the introduction of Grand Central Dispatch. Take a look at the following code snippets. The first snippet downloads data on the main thread, while the second snippet leverages Grand Central Dispatch to perform the same task on a background queue.
如今,GCD已经介绍了,写出安全的多线程代码已经变得很容易,看看下面的代码片段吧.第一段代码是在主线程中下载数据,同时,第二段代码促使GCD在后台队列中做着同样的工作.
NSData *data = [NSData dataWithContentsOfURL:URL];
UIImage *image = [UIImage imageWithData:data];
[imageView setImage:image];
dispatch_queue_t queue = dispatch_queue_create("downloadAsset",NULL);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:URL];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:data];
[imageView setImage:image];
});
});
3. Lazy Loading
Being lazy isn’t always bad especially if you are a programmer. Lazy loading is a well known concept in software development. It simply means that you postpone the instantiation of an object until you need the object. This is advantageous for several reasons. Depending on the object and the cost for instantiation, it can dramatically improve application performance and memory usage. Lazy loading objects isn’t a difficult concept. The simplest implementation of this pattern is overriding the getter of a property as shown below.
如果你是一个码农,偶尔懒惰一下也不是什么坏事.在应用软件领域,延迟加载可谓家喻户晓.很简单,你延时实例化一个对象,直到你真的需要了.他有着几点特别的好处.因为实例化一个对象是需要开销的,(延迟实例化它)能够戏剧性的提升你应用程序的流畅度以及良好的内存使用率.延迟加载对象不是什么难事.最简单的实现就是去重写一个属性的getter方法,看看下面的代码吧.
- (MyClass *)myObject
{
if (!_myObject)
{
_myObject = [[MyClass alloc] init];
}
return _myObject;
}
The lazy loading pattern can be applied in many areas of software development. For example, if part of your application’s user interface is not shown by default, it may be advantageous to postpone its instantiation until that part is about to be shown.
延迟加载的设计方式可以用于很多的软件开发领域.例如,如果你的应用程序的部分UI界面还没有显示出来,那么,当真正到了需要显示的时候,那就实例化出那个对象来显示吧.
Table and collection views use a combination of caching and lazy loading to optimize performance. If the next cell or item is about to be displayed on screen, the table or collection view looks for a cell or item it can reuse (caching). Only if no reusable cell or item is available will the table or collection view (or its data source) instantiate a new cell or item (lazy loading).
table和视图集会用到缓存以及延迟加载来优化程序的性能.如果下一个单元或者物件将要在屏幕上显示出来了,那么table或者视图集就可以重用.仅仅在没有可以重用的单元或者物件的时候,这个时候就创建出一个新的单元或者物件(之后可以重用了).
4. Measure Performance
If you notice that your application is slow at times and you want to find out what is causing it, then you may need to profile your application with a tool such as Instruments. Colin Ruffenach wrote a nice tutorial about time profiling with Instruments on Mobiletuts+.
有时候,你注意到了你的应用程序偶尔会卡顿而且你也想找出到底是什么东西引起的.那么,你就需要一个工具来分析了,例如Instruments.Colin Ruffenach 在网站Mobiletuts+写了 <a nice tutorial about time profiling> 来教你使用 Instruments .
If Instruments doesn’t give you a clear answer, you may be interested in MGBenchmark, a benchmarking library developed and maintained by Mattes Groeger. This compact library lets you measure how fast your code executes and it helps you to track down the bottlenecks in your code base. It actually complements Instruments quite well so you shouldn’t use one or the other. Mattes Groeger’s library comes with an extensive feature set and is remarkably powerful. I highly recommend it as an alternative or complement to Instruments.
如果 Instruments 还是不能给你一个清晰的答案,也许你会对MGBenchmark感兴趣,那就看看Mattes Groeger大神所开发和维护的企业级库,这个牛逼的库能够测试出你的代码能够跑得多快,而且,他还能追踪到你代码的最高运行速度.他真的表现得完美,你根本就不需要其他的了,真的.Mattes Groeger的库有着大量的牛逼的特性,功能非常强大.在这里,我无节操的强烈向你们推荐它.
5. Stress Testing
If you’re developing an application that works with lots of data, then it is important to test it with…well…lots of data! During the development of an application, it isn’t always easy or possible to imagine how your users are going to use your application, but it is good to put it through its paces before releasing it. Your application may perform admirably during development and perform terribly in situations where it is flooded with data. You probably won’t be able to predict, let alone test, all the circumstances in which your application will be used, but you can try to mimic common situations by creating data sets to test with.
如果你开发的应用软件需要处理非常多的数据,好吧,那你就用巨量的数据来测试它!在软件开发阶段,想象着用户怎么暴力玩弄你的软件似乎有点困难,但是呢,发布软件前最好还是进行压力测试.也许开发阶段,应用软件表现良好,但是呢,一旦遇到了海量的数据量时,估计会卡得掉渣.你很有可能无法预测到这点哦,那就进行测试吧,将所有可能出现的情形都测测,有时候,你可以(自己)创建出一些测试数据来模拟现实的情形进行压力测试.
I often create a small script or class that populates the application with test data to measure how well it performs with a lot of data. Ideally, you want to populate the application with more test data than an average user will have – to the extent that you can predict this during development. When I was developing Pixelsync, an iPad application that interfaces with Aperture and iPhoto, I created an Aperture library with close to 500,000 images. If Pixelsync performed well with a photo library of that size, I could be fairly confident that the average user wouldn’t run into performance issues.
我常常会写脚本来装载进程序中来测设数据,测量测量应用程序在面对巨量数据时是否能表现如意.理论上,你需要给出比正常需求更多的数据进行测试.再者,你可以在开发阶段就提前预测.当我在开发Pixelsync(一款iPad应用,可以与Aperture和iPhoto交互)时,我创建了一个Aperture的库,足足有50000张图片.如果Pixelsync能够处理好如此巨量的图片库,那我能十分确信,即使是春哥也玩不坏这款软件.
If you really are a lazy developer or you just don’t have enough time, then you can also be more creative by building a robot to do the job for you.
如果你真的懒得要死,或者要打游戏没有时间,也许,你可以自己造一个机器人来帮你干这些事情......
Conclusion
Application performance remains an essential aspect of software development despite the fact that the new generation of devices are much more powerful and capable. Blocking the main thread, for example, will always result in a bad user experience no matter how capable the device is.
开发应用软件时,软件运行得流畅是非常非常非常重要的,尽管,事实上,每更新一代硬件后,性能都会得到提升.但是,垃圾代码阻塞了主线程,那卡顿的触感是会让用户崩溃而问候开发人员的,无论你硬件的性能有多牛逼.