1. Overview
Reading a Web image through a URL under iOS is not as easy as other programming languages to place the picture path directly in the picture path, but requires us to load the network image through a similar stream, before the image can be placed in the image path display. Like what:
-(UIImage *) Getimagefromurl: (NSString *) FileURL {//nslog (@ "Perform picture download function"); UIImage * result; NSData * data = [NSData Datawithcontentsofurl:[nsurl Urlwithstring:fileurl]]; result = [UIImage imagewithdata:data]; return result;}
Loading network pictures can be said to be a must in network applications. If the simple to download pictures, and not to do multi-threading, caching and other technologies to optimize, loading pictures when the effect and user experience will be very poor.
The optimization idea is:
(1) Local cache
(2) Asynchronous loading
(3) Use placeholder images before loading
2. Optimization method
Method 1: Use Nsoperation to open an asynchronous thread to download the picture and replace the placeholder picture when the download is complete
#import "XNViewController.h" #import "XNApp.h" @interface XNViewController () @property (Nonatomic, strong) NSArray *appList; @property (nonatomic, strong) nsoperationqueue *queue; @end @implementation xnviewcontroller#pragma mark - Lazy Loading- (nsoperationqueue *) queue {if (!_queue) _queue = [[nsoperationqueue alloc] init];return _queue;} It can be extracted and written into the model- (nsarray *) applist {if (!_applist) {//1. Loading plist into an array nsurl *url = [[nsbundle mainbundle] urlforresource:@ "Apps.plist" withExtension:nil]; Nsarray *array = [nsarray arraywithcontentsofurl:url];//2. Iterating through an array Nsmutablearray *arraym = [NSMutableArray array]; [Array enumerateobjectsusingblock: ^ (Id obj, nsuinteger idx, bool *stop) { [arraym addobject:[xnapp appwithdict:objThe]]; //array is stored in the dictionary, converted to an App object and then added to the array}];_applist = [arraym copy];} Return _applist;} - (void) viewdidload {[super viewdidload];self.tableview.rowheight = 88;// nslog (@ "applist-%@", _applist);} #pragma mark - Data source method- (Nsinteger) TableView: (uitableview *) tableview Numberofrowsinsection: (Nsinteger) Section {return self.applist.count;} - (uitableviewcell *) TableView: (uitableview *) Tableview cellforrowatindexpath: (NSIndexPath *) indexpath {static nsstring *id = @ "Cell"; uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:id];// Populate each cellxnapp *app = self.applist[indexpath.row];cell.textlabel.text = app.name; with a model //set text//settings image: The image in the model is nil with the default image, and download the image . otherwise cache the image with the memory in the Model .if (!app.image) { cell.imageview.image = [uiimage imagenamed:@ "User_defAult "]; [Self downloadimg:indexpath];} else {//directly with the memory cache in the model Cell.imageview.image = app.image;} NSLog (@ "cell--%p", cell); Return cell;} /** always remembers, to modify the display . through the model instead of trying to directly modify the display */- (void) downloadimg: (nsindexpath *) Indexpath {xnapp *app = self.applist[indexpath.row]; //to get the model of the row corresponding [self.queue addoperationwithblock: ^{ nsdata *imgdata = [nsdata datawithcontentsofurl:[nsurl urlwithstring:app.icon]]; //Get Image Data UIImage *image = [uiimage imagewithdata:imgdata]; //update ui in the main thread [[NSOperationQueue mainQueue] addOperationWithBlock: ^{ //modify the data by modifying the model, app.image = image; //refreshes the specified table row        &NBsp [Self.tableview reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationnone];}];}];} @end
The code above simply does the memory cache and does not have a local cache, because this method is not the focus, nor is it the preferred method. The above code is re-downloaded from the Web every time you re-enter the app. If you want to continue optimizing the above code, you need to implement the local cache yourself.
Method 2: Use a third-party framework Sdwebimage
Characteristics:
Rely on a few libraries, full-featured.
Automatic disk caching: Cached image names are named after the name of the MD5 encryption. (because the string of encryption is unique)
Set the placeholder image directly when loading the network picture: [ImageView sd_setimagewithurl:imageurl placeholderimage:[uiimage imagenamed:@ "xxxxx"].
In one way, it realizes multi-thread buffering and other effects. (Can be used with the method of parameters, specific to the document)
The code after modifying the above method with Sdwebimage can be simplified to:
#pragma mark - Data source method- (Nsinteger) TableView: (uitableview *) tableview Numberofrowsinsection: (Nsinteger) Section {return self.applist.count;} - (uitableviewcell *) TableView: (uitableview *) Tableview cellforrowatindexpath: (NSIndexPath *) indexpath {static nsstring *id = @ "Cell"; uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:id];// Populate each cellxnapp *app = self.applist[indexpath.row];cell.textlabel.text = app.name; with a model //Set the text////set the image: the image in the model is nil with the default image, and download the image . otherwise use the memory in the model to cache the image .//if (!cell.imageview.image) {//cell.imageview.image = [uiimage imagenamed:@ "User_default"];////[self downloadImg : indexpath];//}//else {////directly with the memory cache in the model//cell.imageview.image = app.image;//}// Use Sdwebimage to complete the above functions . for imageview.//A word, automatic implementation of the asynchronous download . picture local cache . network download . auto-set placeholder. [cell.imageview sd_setimagewithurl:[nsurl urlwithstring:app.icon] placeholderimage:[uiimage imagenamed:@ "User_ Default "]];return cell;} /** always remembers, to modify the display . through the model instead of trying to directly modify the display *///- (void) downloadimg: (nsindexpath *) indexpath {// xnapp *app = self.applist[indexpath.row]; //to get the model of the row corresponding////[self.queue addoperationwithblock: ^{// nsdata *imgdata = [nsdata datawithcontentsofurl:[nsurl urlwithstring:app.icon]]; //Get Image Data// uiimage *image = [uiimage imagewithdata:imgdata];//// //update ui// in the main thread [[NSOperationQueue mainQueue] addOperationWithBlock: ^{// //modifies the data by modifying the model, // app.image = image;// //refreshes the specified table row// &nBsp [self.tableview reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationnone];// }];//}];//} @end
Some of the parameters in the "Remarks" Sdwebimage:
*sdwebimageretryfailed = 1<< 0, default option, retry after failure
*sdwebimagelowpriority = 1<< 1, using low-priority
*sdwebimagecachememoryonly = 1<< 2, using only memory cache
*sdwebimageprogressivedownload = 1<< 3, showing current progress
*sdwebimagerefreshcached = 1<< 4, flush cache
*sdwebimagecontinueinbackground =1 << 5, continue downloading images in the background
*sdwebimagehandlecookies = 1<< 6, processing cookies
*sdwebimageallowinvalidsslcertificates= 1 << 7, allow invalid SSL authentication
*sdwebimagehighpriority = 1<< 8, high-priority
*sdwebimagedelayplaceholder = 1<< 9 delay display placeholder picture
iOS development loads a lot of network picture optimizations