iOS Development multithreading Four: nsoperation multi-Image Download comprehensive case

Source: Internet
Author: User

#import "ViewController.h"#import "XMGAPP.h"@interfaceViewcontroller ()/** Data source for TableView*/@property (nonatomic, strong) Nsarray*apps;/** Memory Cache*/@property (nonatomic, strong) Nsmutabledictionary*images;/** Queue*/@property (nonatomic, strong) Nsoperationqueue*queue;/** Operation Cache*/@property (nonatomic, strong) Nsmutabledictionary*operations;@end@implementationViewcontroller#pragmaMark----------------------#pragmaMark Lazy loading-(Nsoperationqueue *) queue{if(_queue = =Nil) {_queue=[[Nsoperationqueue alloc]init]; //Setting the maximum number of concurrent_queue.maxconcurrentoperationcount =5; }    return_queue;}-(Nsmutabledictionary *) images{if(_images = =Nil) {_images=[Nsmutabledictionary dictionary]; }    return_images;}-(Nsarray *) apps{if(_apps = =Nil) {                //Dictionary ArrayNsarray *arraym = [Nsarray arraywithcontentsoffile:[[nsbundle mainbundle]pathforresource:@"apps.plist"Oftype:nil]]; //Dictionary array----> model ArraysNsmutablearray *ARRM =[Nsmutablearray array];  for(Nsdictionary *dictinchArraym)        {[ARRM Addobject:[xmgapp appwithdict:dict]]; } _apps=ARRM; }    return_apps;}-(Nsmutabledictionary *) operations{if(_operations = =Nil) {_operations=[Nsmutabledictionary dictionary]; }    return_operations;}#pragmaMark----------------------#pragmaMark Uitableviewdatasource-(Nsinteger) Numberofsectionsintableview: (UITableView *) tableview{return 1;}-(Nsinteger) TableView: (UITableView *) TableView numberofrowsinsection: (nsinteger) section{returnSelf.apps.count;}-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) indexpath{StaticNSString *id =@"app"; //1. Create a cellUITableViewCell *cell =[TableView Dequeuereusablecellwithidentifier:id]; //2. Setting the cell's data//2.1 Get the data for the row cellXmgapp *appm =Self.apps[indexpath.row]; //2.2 Setting the titleCell.textLabel.text =Appm.name; //2.3 Setting sub-headingsCell.detailTextLabel.text =Appm.download; //2.4 Setting Icons//go to check the memory cache in the picture when it already exists, if there is so long to use directly, otherwise check the disk cache//If there is a disk cache, then save a copy to the memory, set the picture, or download it directly//1) has not been downloaded//2) Re-open the programUIImage*image =[Self.images ObjectForKey:appM.icon]; if(image) {Cell.imageView.image=image; NSLog (@"Images in the memory cache are used in the picture at%zd", Indexpath.row); }Else    {        //save picture to sandbox cacheNSString *caches =[Nssearchpathfordirectoriesindomains (Nscachesdirectory, Nsuserdomainmask, YES) lastobject]; //get the name of the picture, cannot contain/NSString *filename =[Appm.icon lastpathcomponent]; //full path of stitching picturesNSString *fullpath =[Caches stringbyappendingpathcomponent:filename]; //Check the disk cacheNSData *imagedata =[NSData Datawithcontentsoffile:fullpath];//        //abolished//imageData = nil;                if(imageData) {UIImage*image =[UIImage Imagewithdata:imagedata]; Cell.imageView.image=image; NSLog (@"Pictures in the%zd using a picture from the disk cache", Indexpath.row); //save picture to memory cache[Self.images setobject:image ForKey:appM.icon]; //NSLog (@ "%@", FullPath);}Else        {            //Check the picture when it is being downloaded, if it is so long to capture anything else, then add the download taskNsblockoperation *download =[Self.operations ObjectForKey:appM.icon]; if(download) {}Else            {                                //first empty the cell's original pictureCell.imageView.image = [UIImage imagenamed:@"snip20160221_306"]; Download= [Nsblockoperation blockoperationwithblock:^{Nsurl*url =[Nsurl URLWithString:appM.icon]; NSData*imagedata =[NSData Datawithcontentsofurl:url]; UIImage*image =[UIImage Imagewithdata:imagedata]; NSLog (@"%zd--Download---", Indexpath.row); //fault-tolerant processing                    if(Image = =Nil)                        {[Self.operations RemoveObjectForKey:appM.icon]; return ; }                    //demonstration of Slow speed//[Nsthread sleepfortimeinterval:3.0]; //save picture to memory cache[Self.images setobject:image ForKey:appM.icon]; //NSLog (@ "Download---%@", [Nsthread CurrentThread]); //inter-thread communication[[Nsoperationqueue Mainqueue] addoperationwithblock:^{                                                //cell.imageView.image = image; //Refresh a row[Self.tableview Reloadrowsatindexpaths:@[indexpath] Withrowanimation:uitableviewrowanimationle                        FT]; //NSLog (@ "UI---%@", [Nsthread CurrentThread]);                    }]; //write data to sandbox[ImageData Writetofile:fullpath Atomically:yes]; //to remove a picture from the download operation[Self.operations RemoveObjectForKey:appM.icon];                                }]; //adding actions to the action cache[Self.operations setobject:download ForKey:appM.icon]; //adding actions to the queue[Self.queue Addoperation:download]; }                    }    }        //3. Return to cell    returncell;}-(void) didreceivememorywarning{[Self.images removeallobjects]; //Cancel all operations in the queue[Self.queue cancelalloperations];}//1.UI is not fluent---> Threads download pictures//2. Picture repeat download---> Save the previously downloaded image (dictionary)//Memory Cache---> Disk cache//3. The picture does not refresh---> Refresh a row//4. Image repeat download (image download takes time, and the picture is re-displayed before it is fully downloaded)//5. Data Confusion---setting placeholder images/*Documents: Backup, do not allow Libray Preferences: Preferences Save account Caches: Cache file tmp: Temporary path (can be deleted at any time)*//** * 1: Read files in project: Nsarray *arraym = [Nsarray arraywithcontentsoffile:[[nsbundle mainbundle]pathforresource:@ "apps    . plist "Oftype:nil]";    Read Url;arraywithcontentsofurl 2:KVC: Quickly implement a dictionary to model, the premise must be guaranteed in the Model field value one by one corresponds to + (instancetype) appwithdict: (Nsdictionary *) dict     {Xmgapp *appm = [[Xmgapp alloc]init];    KVC [AppM setvaluesforkeyswithdictionary:dict];    return AppM; } 3: Design ideas: 1: The downloaded pictures are stored in the memory cache and the disk cache, and then go to the memory cache to find if there is no picture, if there is no picture in the memory cache (the picture is directly set image), then go to the disk cache to find the picture, if there is no picture, then go to perform the download operation You also need to save each picture's download operation in the memory cache, after the download is complete, the picture is stored in the memory and the disk cache, and the operation queue is removed from the memory cache, there are pictures, direct settings, and coexistence into the memory cache. 2: Memory cache: is a strong reference to the property variables, generally used in the dictionary to cache, the key value of one by one corresponding to the disk cache: is cached to the sandbox, Documents: will be backed up on the itools, Apple is not allowed to store the cache in Documents, the online will be rejected  Libray: General Libray for storing cache information, large files or offline cached data, which includes the following two paths Preferences: Preferences Save account Caches: Cache file tmp: Temporary path (can be deleted at any time) 4: Specific implementation: 1:nscachesdirectory: Get Libray under the caches folder path, [Appm.icon lastpathcomponent] Get the file extension, generally the extension and path of the file together as a filename// Save picture to sandbox cache nsstring *caches = [Nssearchpathfordirectoriesindomains (nscachesdirectory, Nsuserdomainmask, YES) lastObjeCT]; Get the name of the picture, cannot contain/nsstring *filename = [Appm.icon lastpathcomponent];  Stitching the full path of the picture nsstring *fullpath = [caches stringbyappendingpathcomponent:filename];  2: Check the disk cache NSData *imagedata = [NSData Datawithcontentsoffile:fullpath]; 3: The disk cache has pictures, set, and cached in the memory cache, no picture directly download, first find the cache queue from the cache queue, if there is nothing to do, no, go to create a queue, encapsulate the task Nsblockoperation, (each picture to create a queue, And the queue is cached in the memory cache), inter-thread communication, the child main thread refreshes the UI, the downloaded picture is cached in memory and the disk cache, and the queue is cached in the memory cache for the next use.  4: Also need to have fault-tolerant processing, when the picture download fails, return directly, and remove the queue in the cache if (image = = nil) {[self.operations RemoveObjectForKey:appM.icon]; 5: Problems encountered and solutions://1.ui is not fluent---> Threads download picture//2. Repeat Download---> Save the previously downloaded image (dictionary) memory Cache---> Disk cache//3. The picture does not refresh---> Refresh a line: [Self.tableview Reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationleft]; 4. Picture repeat download (picture download takes time, when the picture has not been fully downloaded, but also to re-display the picture, a quick overflow screen and then back, by setting up the cache queue to solve the problem, so that the queue that was being downloaded is still processing the download task)//5. Data Confusion--- To set up a placeholder picture: Considering the cell reuse mechanism, when a picture is removed from the top of the screen, it will be placed in the cache pool, from the bottom of the entry, from the cache pool to remove the picture, the picture is displayed in the cache pool cell of the picture, the download is completed before the update, the solution is to update the image before the      , the effect is not good, it is best to set the placeholder picture*/@end
#import<Foundation/Foundation.h>@interfaceXmgapp:nsobject/** Name of the app*/@property (nonatomic, strong) NSString*name;/** URL address of the app's picture*/@property (nonatomic, strong) NSString*icon;/** Download volume of App*/@property (nonatomic, strong) NSString*download;+ (Instancetype) appwithdict: (Nsdictionary *) dict;@end
#import " XMGAPP.h " @implementation Xmgapp+ (instancetype) appwithdict: (Nsdictionary *) dict{    *appm = [[Xmgapp alloc]init];    // KVC     [AppM setvaluesforkeyswithdictionary:dict];         return AppM;} @end

Add: HTTPS configuration in plist:

# # #3. Multi-Image Download integrated sample program

(1) Involving knowledge points

01 Dictionary Turn Model

02 storing data into the sandbox, loading data from the sandbox

03 placeholder picture settings (cell refresh problem)

04 How to cache memory (using nsdictionary)

05 Some fault-tolerant processing in the process of program development

06 How to refresh the specified line of TableView (to resolve data confusion issues)

Nsoperation and inter-thread communication related knowledge

iOS Development multithreading Four: nsoperation multi-Image Download comprehensive case

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.