iOS开发之加载大量网络图片优化
2019獨角獸企業重金招聘Python工程師標準>>>
1、概述
在IOS下通過URL讀一張網絡圖片并不像其他編程語言那樣可以直接把圖片路徑放到圖片路徑的位置就ok,而是需要我們通過一段類似流的方式去加載網絡圖片,接著才能把圖片放入圖片路徑顯示。比如:
-(UIImage?*)?getImageFromURL:(NSString?*)fileURL?{//NSLog(@"執行圖片下載函數");????UIImage?*?result;????NSData?*?data?=?[NSData?dataWithContentsOfURL:[NSURL?URLWithString:fileURL]];result?=?[UIImage?imageWithData:data];????return?result; }加載網絡圖片可以說是網絡應用中必備的。如果單純的去下載圖片,而不去做多線程、緩存等技術去優化,加載圖片時的效果與用戶體驗就會很差。
優化思路為:
(1)本地緩存
(2)異步加載
(3)加載完畢前使用占位圖片
2、優化方法
方法1:用NSOperation開異步線程下載圖片,當下載完成時替換占位圖片
#import?"XNViewController.h" #import?"XNApp.h"@interface?XNViewController?() @property?(nonatomic,?strong)?NSArray?*appList; @property?(nonatomic,?strong)?NSOperationQueue?*queue; @end@implementation?XNViewController #pragma?mark?-?懶加載-?(NSOperationQueue?*)queue?{if?(!_queue)?_queue?=?[[NSOperationQueue?alloc]?init];return?_queue; }//可抽取出來寫到模型中 -?(NSArray?*)appList?{if?(!_appList)?{//1.加載plist到數組中NSURL?*url?=?[[NSBundle?mainBundle]?URLForResource:@"apps.plist"?withExtension:nil];NSArray?*array?=?[NSArray?arrayWithContentsOfURL:url];//2.遍歷數組NSMutableArray?*arrayM?=?[NSMutableArray?array];[array?enumerateObjectsUsingBlock:?^(id?obj,?NSUInteger?idx,?BOOL?*stop)?{[arrayM?addObject:[XNApp?appWithDict:obj]];??//數組中存放的是字典,?轉換為app對象后再添加到數組}];_appList?=?[arrayM?copy];}return?_appList; }-?(void)viewDidLoad?{[super?viewDidLoad];self.tableView.rowHeight?=?88;//????NSLog(@"appList-%@",_appList); }#pragma?mark?-?數據源方法 -?(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];//用模型來填充每個cellXNApp?*app?=?self.appList[indexPath.row];cell.textLabel.text?=?app.name;??//設置文字//設置圖像:?模型中圖像為nil時用默認圖像,并下載圖像.?否則用模型中的內存緩存圖像.if?(!app.image)?{cell.imageView.image?=?[UIImage?imageNamed:@"user_default"];[self?downloadImg:indexPath];}else?{//直接用模型中的內存緩存cell.imageView.image?=?app.image;} // NSLog(@"cell--%p",?cell);return?cell; }/**始終記住,?通過模型來修改顯示.?而不要試圖直接修改顯示*/ -?(void)downloadImg:(NSIndexPath?*)indexPath?{XNApp?*app??=?self.appList[indexPath.row];?//取得改行對應的模型[self.queue?addOperationWithBlock:?^{NSData?*imgData?=?[NSData?dataWithContentsOfURL:[NSURL?URLWithString:app.icon]];?//得到圖像數據UIImage?*image?=?[UIImage?imageWithData:imgData];//在主線程中更新UI[[NSOperationQueue?mainQueue]?addOperationWithBlock:?^{//通過修改模型,?來修改數據app.image?=?image;//刷新指定表格行[self.tableView?reloadRowsAtIndexPaths:@[indexPath]?withRowAnimation:UITableViewRowAnimationNone];}];}]; }@end上述代碼只是做了內存緩存,還沒有做本地緩存,因為這里這種方法不是重點,也不是首選方法。上面代碼每次重新進入應用時,還會從網上重新下載。如果要繼續優化上面的代碼,需要自己去實現本地緩存。
方法2:使用第三方框架SDWebImage
特點:
依賴的庫很少,功能全面。
自動實現磁盤緩存:緩存圖片名字是以MD5進行加密的后的名字進行命名.(因為加密那堆字串是唯一的)
加載網絡圖片時直接設置占位圖片:[imageView sd_setImageWithURL:imageurl ?placeholderImage:[UIImage imageNamed:@”xxxxx”]]。
就一個方法就實現了多線程\帶緩沖等效果.(可用帶參數的方法,具體可看頭文件)
用SDWebImage修改上面的方法后的代碼可簡化為:
#pragma?mark?-?數據源方法 -?(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];//用模型來填充每個cellXNApp?*app?=?self.appList[indexPath.row];cell.textLabel.text?=?app.name;??//設置文字// //設置圖像:?模型中圖像為nil時用默認圖像,并下載圖像.?否則用模型中的內存緩存圖像. // if?(!cell.imageView.image)?{ // cell.imageView.image?=?[UIImage?imageNamed:@"user_default"]; // // [self?downloadImg:indexPath]; // } // else?{ // //直接用模型中的內存緩存 // cell.imageView.image?=?app.image; // }//使用SDWebImage來完成上面的功能.?針對ImageView.//一句話,?自動實現了異步下載.?圖片本地緩存.?網絡下載.?自動設置占位符.[cell.imageView?sd_setImageWithURL:[NSURL?URLWithString:app.icon]?placeholderImage:[UIImage?imageNamed:@"user_default"]];return?cell; }/**始終記住,?通過模型來修改顯示.?而不要試圖直接修改顯示*/ //-?(void)downloadImg:(NSIndexPath?*)indexPath?{ // XNApp?*app??=?self.appList[indexPath.row];?//取得改行對應的模型 // // [self.queue?addOperationWithBlock:?^{ // ????NSData?*imgData?=?[NSData?dataWithContentsOfURL:[NSURL?URLWithString:app.icon]];?//得到圖像數據 // ????UIImage?*image?=?[UIImage?imageWithData:imgData]; // // ????//在主線程中更新UI // ????[[NSOperationQueue?mainQueue]?addOperationWithBlock:?^{ // ????????//通過修改模型,?來修改數據 // ????????app.image?=?image; // ????????//刷新指定表格行 // ????????[self.tableView?reloadRowsAtIndexPaths:@[indexPath]?withRowAnimation:UITableViewRowAnimationNone]; // }]; // }]; //}@end【備注】SDWebImage中的一些參數:
*SDWebImageRetryFailed = 1<< 0, ? 默認選項,失敗后重試
*SDWebImageLowPriority = 1<< 1, ? ?使用低優先級
*SDWebImageCacheMemoryOnly = 1<< 2, ? 僅僅使用內存緩存
*SDWebImageProgressiveDownload = 1<< 3, ? 顯示現在進度
*SDWebImageRefreshCached = 1<< 4, ? ?刷新緩存
*SDWebImageContinueInBackground =1 << 5, ? 后臺繼續下載圖像
*SDWebImageHandleCookies = 1<< 6, ? ?處理Cookie
*SDWebImageAllowInvalidSSLCertificates= 1 << 7, ? ?允許無效的SSL驗證
*SDWebImageHighPriority = 1<< 8, ? ? 高優先級
*SDWebImageDelayPlaceholder = 1<< 9 ? ? 延遲顯示占位圖片
轉載于:https://my.oschina.net/u/2448717/blog/502058
總結
以上是生活随笔為你收集整理的iOS开发之加载大量网络图片优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: get,set
- 下一篇: 程序单一实例实现 z