您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何在IOS中加載大量的網絡圖片,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
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]; //用模型來填充每個cell XNApp *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]; //用模型來填充每個cell XNApp *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 延遲顯示占位圖片
關于如何在IOS中加載大量的網絡圖片就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。