25 tips and tricks for enhancing iOS app performance-IntermediateTags: iOS performance optimized memory management2013-12-13 10:55 738 people read comments (0) favorite reports Classification:iphone Development Advanced Series
This article collects 25 tips and tricks for improving program performance into 3 different levels: Beginner, intermediate, and advanced. You can also click to view the introductory article.
In performance optimization, when you encounter some complex problems, you should pay attention to and use the following techniques:
9. Reuse and lazy load view
10. Caching, caching, caching
11. Consider drawing
12. Handling Memory Warnings
13. Reuse of expensive objects
14. Using the sprite Sheets
15. Avoid data re-processing
16. Select the correct data format
17. Set the appropriate background image
18. Reduce the impact of Web content
19. Set the shadow Path
20. Optimize TableView
21. Choose the right data storage method
Intermediate Performance Improvement
Now, when you're doing code optimization, you've been able to perform some of the primary performance optimizations. But there are other optimizations that may be less obvious (depending on the program's architecture and related code), but if you can make the best use of these scenarios, they will be optimized for performance!
9) Reuse and lazy load view
More view is included in the program interface, which means more drawing tasks are required when the interface is displayed, which means more CPU and memory resources are needed. In particular, a lot of view is added to a uiscrollview.
The management techniques for this situation can refer to the behavior of UITableView and Uicollectionview: Do not create all the subview at once, but create the view when needed, and add them to the reuse queue when the view is finished using.
This allows the view to be configured only when the Uiscrollview is scrolled, thus avoiding the cost of assigning create view-which can be very resource-intensive.
Now there is the question of when the view that needs to be displayed in the program is created (for example, when a user taps a button, a view needs to be displayed). There are two options available here:
Create a view when the screen is loaded and hidden for the first time, and then display the view when needed.
The view is created and displayed until you need to display the view.
Each method has its own advantages and disadvantages. The first method consumes more content because the created view occupies memory until the view is released. However, using this method, when the user clicks the button, the program will quickly display the view, because only need to modify the visibility of the view. The second method produces the opposite effect, and when needed, guesses the creation of the view, which consumes less memory, but does not immediately show the view when the user taps the button.
10) cache, cache, cache
When developing a program, an important rule is to "cache what's important"--these things don't change, and the frequency of access is high.
What can I cache to write? For example, the remote server response content, pictures, and even calculate the results, such as the UITableView line height.
Nsurlconnection Some of the resources have been cached to disk and in memory, depending on the HTTP header processing process. You can even create a nsurlrequest manually so that it loads only the cached values.
The following code snippet is typically used to create a nsurlrequest for a picture:
- + (Nsmutableurlrequest *) Imagerequestwithurl: (nsurl *) URL {
- Nsmutableurlrequest *request = [Nsmutableurlrequest Requestwithurl:url];
- Request.cachepolicy = Nsurlrequestreturncachedataelseload; // This would make sure the request always returns the cached image
- Request. Httpshouldhandlecookies = NO;
- Request. httpshouldusepipelining = YES;
- [Request addvalue:@ "image/*" forhttpheaderfield:@ "Accept"];
- return request;
- }
Note: You can use nsurlconnection to crawl a URL request, but you can also use afnetworking to crawl it without having to modify all the network-related code-this is a trick!
For more information about HTTP caching, Nsurlcache, nsurlconnection, and related content, look at the Nsurlcache entry in Nshipster.
If you need to cache content that does not involve HTTP requests, then use Nscache. The appearance and behavior of Nscache is similar to nsdictionary, but when the system needs to reclaim memory, Nscache automatically stores the contents. Mattt Thompson wrote a very good article about Nscache on the nshipster.
For more information on HTTP caching, it is recommended to read this article from Google: best-practices document on HTTP caching.
11) Consider drawing
There are several ways to make beautiful buttons in iOS. You can use a full-size picture to zoom in on a picture, or use Calayer, coregraphics, or even OpenGL to manually measure and draw buttons.
These methods vary in complexity and performance. This article about graphics performance in iOS is worth reading. Andy Matuschak, a member of Apple's Uikit team, has a very good idea of the different approaches and their performance tradeoffs in their comments on this article.
In short, using pre-rendered picture technology is the quickest, because iOS does not have to wait until it is displayed on the screen to create graphics and draw shapes (Pictures have been created!). The problem is that you need to put all the pictures in the program bundle, which increases the size of the program. So using a scalable picture here will come in handy: You can remove the "wasted" space of the picture--ios can be reused. And you don't need to create different pictures for different elements, such as buttons.
However, the use of images will lose the code to control the image, and then for different programs, you need to repeat the generation of each required picture, and repeatedly placed in each program. This process is generally slower. Another point is that if you need an animation, or a lot of images to be slightly adjusted (such as multiple color overlay), then you need to add a lot of pictures in the program, which increases the size of the program bundle.
In general, consider what is most important: drawing performance or program size. is generally important, so in the same project, both should be considered.
12) Handling Memory warnings
When the system memory is low, iOS notifies all programs that are running. Apple's official documentation describes how to handle low memory warnings:
If your app receives this warning, it must free up as much memory as possible. The best-by-do-is-to-remove strong references to caches, image objects, and other data objects so can be Recrea Ted later.
If the program receives a low memory warning, you must try to free the memory in the program. The best way to do this is to remove the cache involved in the strong reference, the picture object, and other data objects that can be recreated later.
The following methods are available in Uikit to receive low memory (low-memory) Warnings:
Implement the Applicationdidreceivememorywarning: method in App delegate.
Override the (override) Didreceivememorywarning method in the Uiviewcontroller subclass.
Register Uiapplicationdidreceivememorywarningnotificatio notification in the Notification center.
Any unwanted memory needs to be released immediately upon receiving any of the above warnings.
For example, the default for Uiviewcontroller is to clear out the currently invisible view, and in the Uiviewcontroller subclass, you can clear some extra data. Images that are not displayed in the current screen in the program can also be removed.
When you receive a low memory warning, it is important to try to free up memory. Otherwise, the running program may be killed by the system.
However, be careful when clearing memory: Make sure that the objects that are purged can also be created. Also, when developing a program, test your program with the simulated memory warning feature in the iOS simulator!
13) Reuse of expensive objects
Some objects are very slow to initialize-such as NSDateFormatter and Nscalendar. However, you can sometimes avoid using these objects, such as when parsing dates in Json/xml.
When using these objects, to avoid performance bottlenecks, try to reuse the objects as much as possible-adding a property to a class or creating a static variable.
Note that if you use a static variable, the object will persist when the program is running, just like a single case.
The following code demonstrates creating a deferred-loading date format property. The first time a property is called, a new date format is created. After that, the instance object that has been created is returned:
- In your. h or inside a class extension
- @property (nonatomic, strong) NSDateFormatter *formatter;
- Inside the implementation (. m)
- When your need, just use Self.formatter
- -(NSDateFormatter *) Formatter {
- if (! _formatter) {
- _formatter = [[NSDateFormatter alloc] init];
- _formatter.dateformat = @"EEE MMM dd HH:mm:ss Z yyyy"; //Twitter date format
- }
- return _formatter;
- }
Also, keep in mind that when you set the date format for NSDateFormatter, it's as slow as creating a new NSDateFormatter instance Object! Therefore, it is very good to reuse the NSDateFormatter if the date format needs to be processed frequently in the program.
14) using Sprite Sheets
Using Sprite Sheets
Are you a game developer? Yes, then the sprite sheets is one of the best choices. Using sprite sheets is quicker to draw and consumes less memory than the usual drawing methods.
Here are two very good sprite sheets tutorials:
How to use animations and sprites in cocos2d Sheets
How to use texture packs (Texture Packer) and pixel formats in cocos2d to create and optimize sprite Sheets. (The second tutorial provides a detailed description of the pixel format-a measure of performance impact in a game)
If you are not familiar with sprite sheets, you can look at the introduction:spritesheets– video, Part 1 and Part 2. The author of these two videos is Andreas Löw, the creator of the texture Pack (Texture Packer), which is an important tool for creating a sprite sheets.
In addition to using sprite sheets, here are some tips for game development, for example, if you have a lot of sprites (like shooting games), you can reuse sprites instead of creating sprites every time.
15) Avoid data re-processing
Many programs need to get data from a remote server to meet the needs of the program. This data is typically in JSON or XML format. It is important to use the same data structure when requesting and receiving data.
Why is it? converting data into a program-appropriate data format in memory is an additional cost.
For example, if you need to display some data in a table view, the data format that is requested and received is preferably in array format, which avoids some intermediate operations-converting the data to a data structure that is appropriate for the application.
Similarly, if a program is accessing a specific value based on a key, it is best to request and receive a dictionary of key/value pairs.
The data obtained at the first time is the desired format and avoids the additional cost of converting the data into a program-friendly data format.
16) Select the correct data format
Select the correct data format
There are several ways to upload data from a program to a network server, where the data format used is basically JSON and XML. All you need to do is choose the correct data format in the program.
JSON is very fast to parse, and is much smaller than XML, which means that you only need to transfer less data. And after IOS5, there is already a built-in JSON deserialization API, so it's easy to use JSON.
However, XML has its own advantages: if you use the Sax method to parse XML, you can read the XML edge parsing, and do not wait until all the XML gets to start parsing, which is different from JSON. This approach improves performance and reduces memory consumption when processing large amounts of data.
17) Set the appropriate background image
In iOS encoding, like many other things, there are two ways to set a background image for a view:
1. You can use the Uicolor Colorwithpatternimge method to create a color and set the color to the background color of the view.
2. You can add a Uiimageview child view to the view.
If you have a full-size background picture, you should use Uiimageview, because Uicolor's Colorwithpatternimge method is used to create a small picture-the image is reused. Using Uiimageview at this time can save a lot of memory.
- You could also achieve the same result in Interface Builder
- Uiimageview *backgroundview = [[Uiimageview alloc] initwithimage:[uiimage imagenamed:@"background"];
- [Self.view Addsubview:backgroundview];
However, if you plan to use small images as backgrounds, you should use the Uicolor Colorwithpatternimge method. In this case, the drawing will be fast and will not consume a lot of memory.
- Self.view.backgroundColor = [Uicolor colorwithpatternimage:[uiimage imagenamed:@"background"];
18) Reduce the impact of Web content
UIWebView is very useful. It makes it easy to display Web content and even to build content that uikit space is difficult to display.
However, you can be able to already notice that the program used by the UIWebView to build a safari program without Apple is fast. This is because JIT compilation restricts the use of the WebKit nitro engine.
So in order to get more performance, you need to adjust the size of the HTML. The first is to get rid of JavaScript as much as possible and avoid using large mines, such as jquery. Sometimes it's faster to use the original JavaScript than the other frames.
Also, try to load JavaScript files asynchronously-especially when the page behavior is not directly affected, such as parsing the script.
Finally-make the images you use the same size as you actually need. As mentioned earlier, use the sprite sheets as much as possible to save memory and improve speed.
For more information, take a look at: WWDC session #601 – Optimize UIWebView and Web content in your website in iOS.
19) Set the shadow path
If you need to add a shadow to the view live layer, how do you handle it? Most developers first add the Quartzcore framework to the project, and then add the following code:
- #import < Quartzcore/quartzcore.h>
- Somewhere later ...
- UIView *view = [[UIView alloc] init];
- Setup the Shadow ...
- View.layer.shadowOffset = Cgsizemake ( -1.0f, 1.0f);
- View.layer.shadowRadius = 5.0f;
- view.layer.shadowOpacity = 0.6;
One problem with this approach is that Core animation must make a off-screen (offscreen) to determine the shape of the view before rendering the shadow effect, and this off-screen operation is very resource-intensive. The following method makes it easier to render the system shaded: Set the shadow Path!
- View.layer.shadowPath = [[Uibezierpath bezierPathWithRect:view.bounds] cgpath];
By setting the shadow path, iOS doesn't always have to calculate how the shadow is drawn. Just use your pre-calculated path. The downside is that, depending on the view format, it may be difficult for you to figure out the path. Another problem is that when the view frame changes, the shadow path must be updated every time.
If you want to learn more about this, see Mark Pospesel's article: Shadowpath.
20) Optimize TableView
Table views require a fast scrolling-if not, the user will feel a pause. To make Table view smooth scrolling, make sure that you follow the following recommendations:
1. Set the correct reuseidentifer to reuse the cell.
2. Try to set the view to opaque, including the cell itself.
3. Avoid gradients, image scaling, and off-screen drawing.
4. If the row height is not the same, then cache it.
5. If the cell displays content to this network, make sure that the content is obtained asynchronously.
6. Use Shadowpath to set the shadow.
7. Reduce the number of subview.
8. Try to do fewer operations in Cellforrowatindexpath:. If you need to do some processing, then it is best to do it once and then cache the results.
9. Use the appropriate data structure to save the required information. Different structures lead to different operating costs.
10. Use RowHeight, Sectionfooterheight, and sectionheaderheight to set a constant height, rather than getting it from the delegate.
21) Choose the right data storage method
Choose the right data storage method
When you need to store and read large amounts of data, how do you choose how to store it? The following options are available:
1. Using Nsuserdefaults for storage
2. Save files in Xml,json or plist format
3. Archiving with nscoding
4. Store to a local database, such as SQLite.
5. Use Core Data.
What's wrong with using nsuserdefaults? Although Nsuserdefaults is good and easy, it is only for storing small amounts of data (such as your level, or the sound is on or off). If you are storing large amounts of data, it is best to choose another storage method.
Storing large amounts of data as structured files can also pose problems. In general, it is very resource-intensive to load all of the content into memory before parsing the structure data. Although you can use Sax to work with XML files, this is a bit complicated. In addition, all objects that are loaded into memory are not necessarily all needed.
So what about using nscoding to save a lot of data? Because it is also read and write to the file, there is still a problem with that.
To save large amounts of data, it is best to use SQLite or core data. With SQLite or core data, you can make specific queries--just get and load the data objects you need--to avoid unreasonable searches of your data. In terms of performance, SQLite and core data do not have much difference.
The biggest difference between SQLite and core data is actually usage. Core data represents an object model, and SQLite is just a DBMS. In general, Apple recommends using core data, but you can use a low-level sqlite if you have a specific reason not to use core data.
In the program, if you choose to use SQLite, here is a handy library Fmdb: You can use the library to manipulate the SQLite database without deep use of the SQLite C API.
25 tips and tricks for improving the performance of iOS apps-intermediate articles