The so-called memory optimization means that in the process of designing a program, we should try to compress the memory occupied by the program while ensuring the efficiency of the program. No matter how large the memory of the hardware device is, the less memory the program occupies when running, the better. Below I will introduce some methods to optimize memory during the development of the project. 1. About UITableView In project development, UITableView is a view control that is used more frequently. If the use of UITableView can be optimized, the performance of the program will be greatly improved. (1) Be good at using the reuse mechanism of UITableViewCell Reuse mechanism: Under this mechanism, the system has a mutable array NSMutableArray* visiableCells by default, which is used to save the currently displayed cells. A mutable dictionary NSMutableDictnery* reusableTableCells is used to save reusable cells. UITableView will only create cells for one screen and put them in visiableCells. Whenever a cell slides out of the screen, it will be put in reusableTableCells. When a cell at a certain position is to be displayed, it will first be taken from reusableTableCells. If it exists, it will be directly used; if not, it will be created. This greatly reduces memory overhead.
After iOS 6, in addition to reusing cells in UITableView and UICollectionView, you can also reuse the Header and Footer of each Section. It can be seen that Apple has been continuously optimizing. In project development, we need to set the correct reuseIdentifier for UITableViewCells, UICollectionViewCells, and UITableViewHeaderFooterViews. When there are multiple types of cells that need to be reused, we can distinguish them based on the reuseIdentifier. We can set it in Xcode, as shown below: The following is a simple example of cell reuse:
Reusing cells is a good mechanism, but improper use can also cause problems, which is the so-called reuse overlap problem. See the following code: I originally planned to set the even-numbered rows to blue, the cardinal-numbered rows to the default color, and set the cell content to the row number to distinguish them. The result is as follows: As can be seen from the above figure, the 13~14 cells initialized at the beginning are normal, but when sliding the tableview, there is a problem, and some of the base row cells also turn blue. This is because the following cells are basically reused. When the properties of the specified cell are not displayed, it will use the properties of the already created cells, resulting in some blue and some white. The solution is to write it as follows: Remember: when assigning attributes to multiple cells, you must not write them inside if (!cell){} to avoid problems with reuse. (2) Optimize UITableViewCell height calculation UITableView has two very important callback methods: tableView:cellForRowAtIndexPath: and tableView:heightForRowAtIndexPath:. Many people think that when initializing the tableview, the former will be called first to create it, and then the latter will be called for layout and property settings. However, this is not the case. The real situation is this: UITableView is inherited from UIScrollView, and it is necessary to determine its contentSize and the position of each Cell before placing the reused Cell in the corresponding position. So in fact, the callback order of UITableView is to call tableView:heightForRowAtIndexPath: multiple times to determine the contentSize and the position of the Cell, and then call tableView:cellForRowAtIndexPath: to display the Cell on the current screen. For example, if 20 cells are to be displayed and the current screen displays 5 cells, when refreshing (reloading) UITableView, UITableView will first call the tableView:heightForRowAtIndexPath: method 20 times, and then call the tableView:cellForRowAtIndexPath: method 5 times; when scrolling the screen, each time a cell scrolls into the screen, the tableView:heightForRowAtIndexPath: and tableView:cellForRowAtIndexPath: methods will be called once. Therefore, the optimization of UITableViewCell height calculation is to process these two functions. As for how to optimize @我叫Sunny什么了 wrote a very good article to introduce it. I won't say more. (3) Lazy loading (delayed loading) Lazy loading does not reduce the memory consumption of the program, but postpones the time of loading objects and initializes them when they are used. For example, a UITableView has 20 rows, but the screen only displays 5 rows of arrays. Then when initializing the tableview, you can only load 5 rows of data first, and then load the other 15 rows when they are displayed. This can reduce the memory required to initialize the tableview. (This is a bit far-fetched, because real-time loading will affect the smoothness of the tableview, but this is the general idea><) 2. About image processing Images take up a lot of memory overhead. If you process images properly, you can reduce a lot of memory consumption. (1) Cache images There are two common ways to load images from a bundle, one is to use imageNamed, the other is to use imageWithContentsOfFile, the first one is more common. The advantage of imageNamed is that it caches the image when it is loaded. The imageNamed documentation says: This method searches the system cache for an image object with the specified name and returns it if it exists. If the image is not found in the cache, this method loads it from the specified document and then caches it and returns the object. That is to say, the image loaded by the imageNamed method will cache the image, while the imageWithContentsOfFile method will not. Therefore, if the image to be loaded is relatively small and will be used repeatedly, choose to use imageNamed in this case; if you want to load a large image and use it once, use imageWithContentsOfFile, there is no need to waste memory to cache it. Code example: (2) Adjust the image size We often get pictures from the Internet or from local bundles, and then load them into UIImageView. When loading pictures, we should try to ensure that the picture size is the same as the UIImageView size. Because scaling pictures at runtime is very resource-intensive, if the UIImageView is nested in a UIScrollView or UITableView, it will consume even more resources. For images loaded from a local bundle, we can process the images beforehand. For images downloaded from the Internet, we need to scale the images after downloading them and then load them. (3) Code rendering or direct acquisition As mentioned above, using code to render an image will double the memory usage of the image. However, using code to draw images can give you good control over the image and produce many beautiful effects, but at the cost of some memory. What if all images are loaded from a bundle? That will increase the size of the bundle and prevent you from using code to flexibly process the effects of the images. Therefore, during the development process, you need to make a trade-off between rendering images with code or getting images from the bundle. 3. Data processing In project development, we will use data in various formats, such as JSON, XML, etc. There are also various data structures, such as arrays, linked lists, dictionaries, collections, etc. Using the correct data format and using the correct data structure will reduce our resource consumption. (1) Choose the correct data format When apps interact with the network, they often use JSON or XML data formats. JSON is a lightweight data exchange format that is easy to read and write quickly. Parsing JSON is faster than XML, but the data transmitted by JSON is relatively small. XML is a heavyweight data exchange format suitable for large data transmission. When the amount of data is large, using XML data format will greatly reduce memory consumption and increase performance. In addition, try to avoid multiple data conversions. For example, if the tableview needs to be assigned in the form of an array, then the server should try to return the array type. If the JSON type is returned, converting it to the NSArray type will also increase the overhead. (2) Choose the right data structure Different data structures process data at different speeds. Array NSArray NSMutableArray: An ordered set of values. Fast to search using index, slow to search using value, slow to insert/delete. Dictionary NSDictionary NSMutableDictionary: stores key-value pairs. Using keys to search is faster. NSSet NSMutableSet: An unordered set of values. Fast lookup by value, fast insertion/deletion. 4.View processing (1) Avoid using overly complex xibs Xibs are still frequently used in many current project developments. When a xib is loaded, all of its contents are put into memory, including any images. If the xib file is too large, it will take up a lot of memory. Unlike storyboards, xib views will exist in memory even if they are not used temporarily; storyboards only instantiate a view controller when needed. Also, when setting the view properties, try to set the opaque property to YES (opaque). This will help the rendering system optimize some rendering processes and improve performance. (2) Correctly set the background of the View There are two main ways to set the background image of UIView: Use UIColor's colorWithPatternImage to set the background color; Add a UIImageView subview to the UIView. The first method is suitable for creating backgrounds with small tiles, which can render faster and does not take up a lot of memory. For example, use a 10x10 pixel size repeating background. The second method is suitable for using large images, that is, the entire image to set the background. If colorWithPatternImage is used, it will consume too much memory and receive a memory warning, causing the application to crash suddenly. Using UIImageView will save a lot of memory. (3) Setting Shadow Path If you add a shadow to view.layer using the following code: This will force Core Animation to derive the graphics and add shadows in the background before rendering, which is very expensive. If you use shadowPath you will avoid this problem: 5. Reasonable use of Autorelease Pool NSAutoreleasePool is responsible for releasing the autoreleased objects in the block. Generally, it will be automatically called by UIKit. However, in some cases, you need to create it manually. If you create a lot of temporary objects, you will find that the memory keeps decreasing until these objects are released. This is because the memory will not be released until UIKit runs out of autorelease pool. But if you define @autoreleasepool yourself and create temporary objects in it, you can avoid this problem: 6. Handle caching correctly Cache can be divided into memory cache and disk cache. During project development, we often cache some pictures, sounds, and data. Reasonable use of the cache mechanism will greatly improve the performance of the program and improve the fluency of the APP. For example, the widely used SDWebImage uses the following cache mechanism: (1) First check the memory cache, if any, obtain it directly. (2) If the data is not in memory, obtain it from the disk cache. (3) If there is no disk cache, download it directly from the Internet through the URL. Of course, this is just a simple description. For more details, please see @南峰子_老驴's SDWebImage implementation analysis. Proper handling of cache can improve the performance of the program, and it is not necessary to obtain data from the network every time. However, you cannot store everything in the cache, which will consume a lot of memory and disk space. Therefore, the cache mechanism should be used reasonably. summary The above is my understanding of memory optimization. In the process of writing this article, I referred to many articles by experts. As a fresh undergraduate, my understanding of OC is still very shallow. If there are mistakes or things that need to be added, I hope you can point them out. I will correct them and learn from them. |
<<: How wearables can help players compete at the World Cup
>>: Some summary thoughts on Android plug-in
Not long after the launch of Xiaomi Note, a top-e...
[[141390]] This tutorial has been updated for Swi...
When it comes to freeze-dried fruit and vegetable...
Decades ago, someone planned to blast a hole in t...
Sometimes we are very confident in our own copywr...
During the Spring Festival holiday, most people w...
Why is my ad not getting any exposure no matter h...
Qinggua Media News: In the early morning of Janua...
01. Changes in the communication model: From manu...
360 resources are online and offline, and product...
Expert of this article: Zhang Zheng, PhD in Nutri...
Written by Wei Shuihua Header image | Visual Chin...
How much does it cost to customize a catering min...
Apple's goal is to make the iPhone the only t...
Why do you want to create a WeChat video account?...