This article is reproduced from:Anxonli
The last time I wrote an iPad app development article for 10 months, I had a good overview of the iPad app development. It once became the first search keyword for the Google Keyword "iPad app development, it may be that the scalpers are too busy making money for the app store. I will leave this shrimp to write articles. This article focuses on iOS multi-core programming and memory management. Why? Because iPad 2 is already a dual-core CPU! Although the iPad 1 application is no longer slow, you can use Apple's multi-core programming framework to write more responsive applications.
Multi-core operations
In iOS, The concurrency programming framework is gcd (Grand Central Dispatch), which is very simple to use. It distributes tasks to different queue queues for processing. The developer installs the task code into blocks, and the operating system distributes the task code to different resources for processing. A simple example shows why when a beginner writes tableview, the slide list is always very slow, because many beginners put the image to the main thread for execution. For example, if we want to slide smoothly, IOS can refresh 60 times in one second at most, if your cell's text and images are loaded for more than 1/60 seconds, they will naturally become stuck. Therefore, we usually need to remove the image from the main thread for processing. For GCD, it is to load the image into another queue for asynchronous execution, when the resource is ready, it is displayed in main thread. Main thread is the main queue in GCD.
Code for creating a new queue:
Dispatch_queue_t network_queue; <br/> network_queue = dispatch_queue_create ("com. MyApp. Network", nill );
For example, we put the image reading to network_queue for asynchronous execution.
Dispatch_async (network_queue, ^ {<br/> uiimage * cellimage = [self loadmyimagefromnetwork: image_url]; <br/> // cache the image locally <br/> [self cacheimage: cellimage]; </P> <p> ..... </P> <p> });
Dispatch_async refers to Asynchronous Parallel Processing of a task. It does not need to be processed before processing the next task. The above code loadmyimagefromnetwork refers to reading images from the network. This task is handed over to network_queue for processing. In this way, the processing of the main thread interface will not be blocked if the image reading time is too long.
After processing the image, we should update the interface and design it from the queue concept, that is, to put the code of the updated interface into the main queue, because IOS always uses the main thread to refresh the UI. So the code should be,
Dispatch_async (network_queue, ^ {<br/> uiimage * cellimage = [self loadmyimagefromnetwork: image_url]; <br/> // cache the image locally <br/> [self cacheimage: cellimage]; </P> <p> // return to the main thread <br/> dispatch_async (dispatch_get_main_queue (), ^ {<br/> // display the image to the interface <br/> [self displayimagetotableview: cellimage]; <br/>}]; </P> <p> });
The dispatch_get_main_queue () function returns the main thread, and the ^ {} encapsulates the task code. In this way, the nesting mode can jump from one queue to another, which is so simple.
Generally, we can put networking-related code into a queue, and put the code of the image resize into another queue. After processing, we update the interface and just need to jump back to the main queue nested. By adding a few lines of code, your program can use the system's multi-core resources and assign the specific scheduling work to the operating system itself. With such code, whether your hardware is single-core, dual-core, iMac 4-core, or even 8-core, it can be processed in parallel very well.
Memory Management
I have been amazed at the memory processing capabilities of iOS and objective-C, such as the iwork of the iPad version. The pages application is an amazing work of the memory processing technology application. Think about the M memory iPad, which can bring such a gorgeous interface and get such a smooth user experience, is really not simple. The reason is that IOS has always advocated developers to write the optimal code within limited hardware resources, with the Minimum CPU usage and the minimum memory usage.
(The following code applies to iOS SDK 4.1. Because the new SDK 4.2 has a new change to memory usage, it may be different ...)
1. Minimize the number of uiview Layers
We usually like to put many control layers (uilabel, uibutton, uiview, etc.) together in a large uiview container to display our content. This method is generally acceptable, however, if you need to refresh the large area interface of the content frequently, most of them occur in iPad applications, this method will bring too much memory usage and animation latency (relatively slow), for example, scrollview animation comparison card, or, often receive a memory warning. One important reason is that each control, especially the transparent bottom, will be redrawn multiple times (drawrect) too much. The solution is to merge several controls into one layer for display as much as possible, so that the system will reduce the number of calls to drawrect, resulting in performance improvement.
In a simple example, iNotes provides the handwriting function. You can write different strokes on the iPad screen. The initial design is that each stroke is written by the user, iNotes will generate a new transparent uiview to keep this stroke. After you write 10 strokes, the system will produce 10 uiviews. The size of each view is the whole screen, this allows you to perform undo operations. This solution brings serious memory problems, because the system maintains a bitmap for each layer, and a pixel requires 4 bits. The size of a layer is 4x1024x768 ~ 3 M, 10 layers are 10x3 M = 30 m, it is obvious that the iPad soon broke out the memory warning.
The final solution of this example is that all strokes are painted on the same layer, and iNotes can save the points of the strokes for Undo operations. This solution is to redraw the same resource on the Interface no matter how many strokes you draw.
2. display images of the optimal size
Many programmers are too lazy to use uiimageview to display images taken from the Internet. The consequence is that the program needs to keep large images in the memory. The solution should be to first reduce the image size to be displayed, release the memory size of the large image, and then display it to the user interface.
3. Try to use the image pattern instead of a large image.
For example, many interface designers like to place a large basemap on the interface, but this basemap is always occupying memory. The best solution is to design a small pattern, then, use this scheme to display it as a basemap.
Uiimage * smallimage = [[uiimage alloc] paths: path]; <br/> backgroundview. backgroundcolor = [uicolor colorwithpatternimage: smallimage]; <br/> [smallimage release];
4. release resources immediately after they are used
In general, the habit of objective-C is to release the used resources immediately, because it is the programmer who knows when to use a resource.
For example, we want to read a large image, narrow it down, and display it on the interface. Release the large image immediately after it is used. The Code is as follows:
Uiimage * fullscreenimage = [[uiimage alloc] initwithcontentoffile: path]; <br/> uiimage * smallimage = [self resizeimage: fullscreenimage]; <br/> [fullscreenimage release]; <br/> imageview. image = smallimage; <br/> ......
5. The autorelease object is automatically released in a large number of cycles. You can consider using autorelease pool encapsulation.
Sample Code:
For (uiview * subview in bigview. subviews) {<br/> // use autorelease pool to automatically release the object pool <br/> NSAID utoreleasepool * Pool = [[NSAID utoreleasepool alloc] init]; <br/> uiimageview * imageview = (uiimageview *) subview; </P> <p> // subview processing code <br/> ....... <br/> // destroy the automatically released object <br/> [pool drain]; <br/>}
The automatic release Object pool releases the temporary objects generated in each cycle immediately after they are used.
The above comments are my years of experience in writing iPad/iPhone programs. In addition, after the multi-tasking feature of ios4.0 is released, the program can be transferred to the background for operation. Apple's opinion is, when running in the background, your application should release objects that can be released, and keep them around 16 MB as much as possible, so that other programs cannot easily squeeze out your application.
--------------------------------------------------
I haven't written anything for too long, and my Chinese writing skills have regressed. Don't be surprised. Give me more comments.