IOS開發(fā)中加載大量網(wǎng)絡(luò)圖片優(yōu)化方法
IOS開發(fā)中加載大量網(wǎng)絡(luò)圖片如何優(yōu)化
1、概述
在IOS下通過URL讀一張網(wǎng)絡(luò)圖片并不像其他編程語言那樣可以直接把圖片路徑放到圖片路徑的位置就ok,而是需要我們通過一段類似流的方式去加載網(wǎng)絡(luò)圖片,接著才能把圖片放入圖片路徑顯示。比如:
-(UIImage *) getImageFromURL:(NSString *)fileURL {
//NSLog(@"執(zhí)行圖片下載函數(shù)");
UIImage * result;
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
result = [UIImage imageWithData:data];
return result;
}
加載網(wǎng)絡(luò)圖片可以說是網(wǎng)絡(luò)應(yīng)用中必備的。如果單純的去下載圖片,而不去做多線程、緩存等技術(shù)去優(yōu)化,加載圖片時的效果與用戶體驗就會很差。
優(yōu)化思路為:
(1)本地緩存
(2)異步加載
(3)加載完畢前使用占位圖片
2、優(yōu)化方法
方法1:用NSOperation開異步線程下載圖片,當(dāng)下載完成時替換占位圖片
#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到數(shù)組中
NSURL *url = [[NSBundle mainBundle] URLForResource:@"apps.plist" withExtension:nil];
NSArray *array = [NSArray arrayWithContentsOfURL:url];
//2.遍歷數(shù)組
NSMutableArray *arrayM = [NSMutableArray array];
[array enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
[arrayM addObject:[XNApp appWithDict:obj]]; //數(shù)組中存放的是字典, 轉(zhuǎn)換為app對象后再添加到數(shù)組
}];
_appList = [arrayM copy];
}
return _appList;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.rowHeight = 88;
// NSLog(@"appList-%@",_appList);
}
#pragma mark - 數(shù)據(jù)源方法
- (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; //設(shè)置文字
//設(shè)置圖像: 模型中圖像為nil時用默認(rèn)圖像,并下載圖像. 否則用模型中的內(nèi)存緩存圖像.
if (!app.image) {
cell.imageView.image = [UIImage imageNamed:@"user_default"];
[self downloadImg:indexPath];
}
else {
//直接用模型中的內(nèi)存緩存
cell.imageView.image = app.image;
}
// NSLog(@"cell--%p", cell);
return cell;
}
/**始終記住, 通過模型來修改顯示. 而不要試圖直接修改顯示*/
- (void)downloadImg:(NSIndexPath *)indexPath {
XNApp *app = self.appList[indexPath.row]; //取得改行對應(yīng)的模型
[self.queue addOperationWithBlock: ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到圖像數(shù)據(jù)
UIImage *image = [UIImage imageWithData:imgData];
//在主線程中更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock: ^{
//通過修改模型, 來修改數(shù)據(jù)
app.image = image;
//刷新指定表格行
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
}];
}
@end
上述代碼只是做了內(nèi)存緩存,還沒有做本地緩存,因為這里這種方法不是重點,也不是首選方法。上面代碼每次重新進(jìn)入應(yīng)用時,還會從網(wǎng)上重新下載。如果要繼續(xù)優(yōu)化上面的代碼,需要自己去實現(xiàn)本地緩存。
方法2:使用第三方框架SDWebImage
特點:
依賴的庫很少,功能全面。
自動實現(xiàn)磁盤緩存:緩存圖片名字是以MD5進(jìn)行加密的后的名字進(jìn)行命名.(因為加密那堆字串是唯一的)
加載網(wǎng)絡(luò)圖片時直接設(shè)置占位圖片:[imageView sd_setImageWithURL:imageurl placeholderImage:[UIImage imageNamed:@”xxxxx”]]。
就一個方法就實現(xiàn)了多線程\帶緩沖等效果.(可用帶參數(shù)的方法,具體可看頭文件)
用SDWebImage修改上面的方法后的代碼可簡化為:
#pragma mark - 數(shù)據(jù)源方法
- (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; //設(shè)置文字
// //設(shè)置圖像: 模型中圖像為nil時用默認(rèn)圖像,并下載圖像. 否則用模型中的內(nèi)存緩存圖像.
// if (!cell.imageView.image) {
// cell.imageView.image = [UIImage imageNamed:@"user_default"];
//
// [self downloadImg:indexPath];
// }
// else {
// //直接用模型中的內(nèi)存緩存
// cell.imageView.image = app.image;
// }
//使用SDWebImage來完成上面的功能. 針對ImageView.
//一句話, 自動實現(xiàn)了異步下載. 圖片本地緩存. 網(wǎng)絡(luò)下載. 自動設(shè)置占位符.
[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]; //取得改行對應(yīng)的模型
//
// [self.queue addOperationWithBlock: ^{
// NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到圖像數(shù)據(jù)
// UIImage *image = [UIImage imageWithData:imgData];
//
// //在主線程中更新UI
// [[NSOperationQueue mainQueue] addOperationWithBlock: ^{
// //通過修改模型, 來修改數(shù)據(jù)
// app.image = image;
// //刷新指定表格行
// [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
// }];
// }];
//}
@end
【備注】SDWebImage中的一些參數(shù):
*SDWebImageRetryFailed = 1<< 0, 默認(rèn)選項,失敗后重試 *SDWebImageLowPriority = 1<< 1, 使用低優(yōu)先級 *SDWebImageCacheMemoryOnly = 1<< 2, 僅僅使用內(nèi)存緩存 *SDWebImageProgressiveDownload = 1<< 3, 顯示現(xiàn)在進(jìn)度 *SDWebImageRefreshCached = 1<< 4, 刷新緩存 *SDWebImageContinueInBackground =1 << 5, 后臺繼續(xù)下載圖像 *SDWebImageHandleCookies = 1<< 6, 處理Cookie *SDWebImageAllowInvalidSSLCertificates= 1 << 7, 允許無效的SSL驗證 *SDWebImageHighPriority = 1<< 8, 高優(yōu)先級 *SDWebImageDelayPlaceholder = 1<< 9 延遲顯示占位圖片
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
iOS系統(tǒng)緩存方面開發(fā)的相關(guān)基礎(chǔ)
這篇文章主要介紹了iOS系統(tǒng)緩存方面開發(fā)的相關(guān)基礎(chǔ),示例代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-10-10
IOS App圖標(biāo)和啟動畫面尺寸詳細(xì)介紹
這篇文章主要介紹了IOS App圖標(biāo)和啟動畫面尺寸詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-02-02
iOS開發(fā)之導(dǎo)航欄各種右滑返回失效的解決方法匯總
這篇文章主要給大家總結(jié)介紹了關(guān)于iOS開發(fā)教程之導(dǎo)航欄各種右滑返回失效的解決方法,文中通過示例代碼介紹的非常詳細(xì),對各位iOS具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
深入理解Objective-C中類的數(shù)據(jù)結(jié)構(gòu)
最近發(fā)現(xiàn)用Objective-C確實好容易,下面這篇文章主要給大家介紹了關(guān)于Objective-C中類的數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05

