IOS-network images are asynchronously loaded and saved to the sandbox through the NSOperation thread

Source: Internet
Author: User
Tags file url

IOS-network images are asynchronously loaded and saved to the sandbox through the NSOperation thread

During iOS development, many large images are often downloaded and displayed in the UIImageView on the secondary interface. For example, you can view images of multiple cards.
Of course, if you place the image download time-consuming operation in the main thread operation, the program will be suspended. Therefore, consider using the method of asynchronous multi-thread loading and adding inter-thread dependencies, improve user experience as much as possible.
Before that, we need some knowledge reserves: 1. Thread dependency. 2. Sandbox Storage
1. Thread dependency.
Currently, there are two advanced synchronization APIs available for iOS and OS X: NSOperation and GCD. GCD is the underlying C-based API, while NSOperation is the Objective-c api implemented by GCD. Although NSOperation is implemented based on GCD, we can use NSOperation to easily implement things where GCD needs to write a lot of code.
Operation queue is a Cocoa abstraction of a queue model provided by GCD. GCD provides more underlying control, while operation queue provides some convenient functions on GCD. These functions are usually the best and safest choice for app developers.

// Add A dependency operation before the NSOperationQueue thread-(void) dependency {/** assume that there are three operations A, B, and C. Requirements: 1. all three operations are executed asynchronously. operation C depends on Operation B 3. operation B depends on operation A * // create A queue NSOperationQueue * queue = [[NSOperationQueue alloc] init]; // The maximum number of threads that can be opened. maxConcurrentOperationCount = 3; // create three tasks: NSBlockOperation * operationA = [NSBlockOperation blockOperationWithBlock: ^ {NSLog (@ "the current thread of A task is: % @", [NSThread currentThread]);}]; NSBlockOperation * operationB = [NSBlockOperation blockOperationWithBlock: ^ {NSLog (@ "the current thread of the B task is: % @", [NSThread currentThread]);}]; NSBlockOperation * operationC = [NSBlockOperation blockOperationWithBlock: ^ {NSLog (@ "the current thread of the C task is: % @", [NSThread currentThread]) ;}]; // sets the dependency between the three tasks. // operationB depends on operationA [operationB addDependency: operationA]; // operationC tasks depend on operationB [operationC addDependency: operationB]; // Add operations to the queue (automatic asynchronous execution of tasks, concurrency) [queue addOperation: operationA]; [queue addOperation: operationB]; [queue addOperation: operationC];}

2. Sandbox Storage
IOS Data Storage Methods
Directly run the Code:

// 1. obtain the local cache file path NSString * cachePath = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex: 0]; // 2. save the final file name of the file URL as the file name to the local device-> file name NSString * imageFilePath = [cachePath stringByAppendingPathComponent: imageName]; // 3. write the file [UIImagePNGRepresentation (image) writeToFile: imageFilePath atomically: YES];

Reserve completed, let's get down to the truth
No matter what you do, first clarify the objectives:
When a network request succeeds, many image paths are obtained. Do you need to download and display the images on the second-level interface?

Implementation ideas:
1. NSOperationQueue multithreading (adding dependencies) puts the image download operation in different threads for execution.
2. How to add dependencies: the jump operation depends on all download tasks.
3. Save the downloaded image data in the sandbox (the cached image is usually placed in the Cache folder and can be cleared later)-make sure that this data does not exist in the sandbox.
4. Jump to display the multi-chart Interface

Implementation Code:
First, add the NSOperationQueue attribute and load it lazily.

/** Create a queue */@ property (nonatomic, strong) NSOperationQueue * queue; @ end @ implementation RadarController // download queue-(NSOperationQueue *) queue {if (_ queue = nil) {_ queue = [[NSOperationQueue alloc] init]; // maximum number of opened threads [_ queue setMaxConcurrentOperationCount: 10];} return _ queue ;}

Obtain the image path for network requests, and use the most efficient native NSJSONSerialization to parse JSON data

// NSDictionary * result = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: nil]; NSLog (@ "request succeeded... % @ ", result); NSDictionary * dataDict = [result objectForKey: @" result "];

Successfully parsed data:

Final jump operation (interface jump) <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwcmUgY2xhc3M9 "brush: java;"> # Pragma mark-jump to the second-level interface to display the downloaded image-(void) startUpdatingRadar {typeof (self) _ weak weakSelf = self; // delayed operation, after 0.1 seconds, push the dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (0.1 * NSEC_PER_SEC) in the main thread, dispatch_get_main_queue (), ^ {DiffusionController * diffusion = [[DiffusionController alloc] initWithJokeImageArr: _ jokeImageDataArrM]; [diffusion setHidesBottomBarWhenPushed: YES]; [self. navigationController pushViewController: diffusion animated: YES] ;});}

Image download and sandbox Storage Methods: import the image path and image name (the file name saved in the sandbox) to download and save the sandbox operation

# Pragma mark-download an image from the requested image path. // you need to download the image in an asynchronous thread! // According to the image path URL-> Add download task (asynchronous thread)-> Save the downloaded image locally-> to read the downloaded image directly from the file on the second-level interface-(void) downloadImageWithURL :( NSString *) URLStr WithImageName :( NSString *) imageName {// Use thread dependency @ autoreleasepool {NSLog (@ "current thread number: % @", [NSThread currentThread]); // The runloop in the Child thread is disabled by default, which means that the automatic release pool will not be created automatically, and the autorelease object in the Child thread will not be released. In this case, you cannot release the cotton at the same position, causing memory leakage. Therefore, you need to manually create the cotton. // 1. obtain the local cache file path NSString * cachePath = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex: 0]; // 2. save the final file name of the file URL as the file name to the local device-> file name NSString * imageFilePath = [cachePath stringByAppendingPathComponent: imageName]; // if the current file name does not exist in the cache folder, write the file if (! [Self isFileExist: imageName]) {// download image NSData * imageData = [NSData dataWithContentsOfURL: [NSURL URLWithString: URLStr]; // initialize image UIImage * image = [UIImage imageWithData: imageData]; // Save the downloaded image to a local device. // 3. write File // [UIImagePNGRepresentation (image) writeToFile: imageFilePath atomically: YES]; // or-> (this method reduces the cache size, but the image is not clear) [UIImageJPEGRepresentation (image, 0.8) writeToFile: imageFilePath atomically: YES] ;}}// judge the file Is it already in the sandbox? -(BOOL) isFileExist :( NSString *) fileName {NSArray * paths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES); NSString * path = [paths objectAtIndex: 0]; NSString * filePath = [path stringByAppendingPathComponent: fileName]; NSFileManager * fileManager = [NSFileManager defaultManager]; BOOL result = [fileManager fileExistsAtPath: filePath]; NSLog (@ "this file already exists?: % @ ", Result? @ "": @ ""); Return result ;}

Core code. After all download tasks are executed, the Executive Director->

// Create a supervisor-jump to the page _ block NSBlockOperation * jumpMainOperaion = [NSBlockOperation blockOperationWithBlock: ^ {[self startUpdatingRadar];}]; // model array _ jokeImageDataArrM = [[NSMutableArray alloc] init]; // traverses all image paths and adds them to the download queue for (NSDictionary * imageDict in (NSArray *) [dataDict objectForKey: @ "data"]) {JokeImageData * jokeImageData = [[JokeImageData alloc] init]; [jokeImageData setContent: [imageDict objectForKey: @ "content"]; NSString * imageUrl = [imageDict objectForKey: @ "url"]; [jokeImageData setUrl: imageUrl]; NSString * imageName = [imageDict objectForKey: @ "hashId"]; [jokeImageData setHashId: imageName]; [jokeImageData setUpdatetime: [imageDict objectForKey: @ "updatetime"]; // download NSBlockOperation * currentBlockOperation = [NSBlockOperation blockOperationWithBlock from an asynchronous thread: ^ {// image download operation [self downloadImageWithURL: imageUrl WithImageName: imageName];}]; // Add dependency [jumpMainOperaion addDependency: currentBlockOperation]; // Add to thread queue [self. queue addOperation: currentBlockOperation]; // model array [_ jokeImageDataArrM addObject: jokeImageData];} // Add the last operation to the queue [self. queue addOperation: jumpMainOperaion];

A brief flowchart is provided:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.