亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

iOS異步下載圖片實(shí)例代碼

 更新時(shí)間:2016年08月05日 17:09:46   作者:貍貓醬  
這篇文章主要介紹了iOS異步下載圖片實(shí)例代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

寫在前面

在iOS開發(fā)中,無論是在UITableView還是在UICollectionView中,通過網(wǎng)絡(luò)獲取圖片設(shè)置到cell上是較為常見的需求。盡管有很多現(xiàn)存的第三方庫(kù)可以將下載和緩存功能都封裝好了供開發(fā)者使用,但從學(xué)習(xí)的角度出發(fā),看懂源碼,理解其中的原理,結(jié)合自身的實(shí)際需求寫出自己的代碼是很必要的。在剛結(jié)束的Demo中,有用到異步圖片下載功能,這篇筆記就是對(duì)整個(gè)實(shí)現(xiàn)的簡(jiǎn)單整理。

基本思路

•cell中添加一個(gè)UIImageView

•cell擁有url,發(fā)起下載請(qǐng)求,注冊(cè)下次完成通告,在通告處理時(shí)間中獲取下載圖片并設(shè)置

•下載管理類負(fù)責(zé)開啟下載線程和各種緩存(內(nèi)存+文件),下載完成后發(fā)送下載完成通告

•為避免cell重用和異步下載造成的圖片錯(cuò)位,cell在發(fā)起下載前為自身imageView設(shè)置默認(rèn)圖片,同時(shí)為imageView設(shè)置tag

整體框架

 

關(guān)鍵代碼

cell初始化,并注冊(cè)下載完成通告

@interface SQPhotoCell ()
@property (strong, nonatomic) UIImageView *photoView;
//Tag指向當(dāng)前可見圖片的url,可過濾掉已經(jīng)滑出屏幕的圖片的url
@property (strong, nonatomic) NSString *imageViewTag;
@end
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
_photoView = [[UIImageView alloc] initWithFrame:CGRectZero];
_photoView.userInteractionEnabled = YES;
[self.contentView addSubview:_photoView];
_imageViewTag = @"";
//注冊(cè)下載完成通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(downloadCallback:)
name:NOTIFICATION_DOWNLOAD_CALLBACK
object:nil];
}
return self;
}

cell通知處理事件

//通知處理事件
- (void)downloadCallback:(NSNotification *)noti
{
NSDictionary *notiDic = noti.userInfo;
NSString *urlStr = [notiDic objectForKey:@"urlStr"];
UIImage *image = [notiDic objectForKey:@"image"];
if ([self.imageViewTag isEqualToString:urlStr])
{
self.photoView.image = image;
}
}

cell發(fā)起下載請(qǐng)求

- (void)setImageWithURL:(NSString *)urlStr placeholder:(UIImage *)placeholder
{
self.imageViewTag = urlStr;
//預(yù)設(shè)圖片,用于清除復(fù)用以前可能存在的圖片
self.photoView.image = placeholder;
if (urlStr)
{
SQWebImageManager *manager = [SQWebImageManager sharedManager];
[manager downloadImageWithURLString:urlStr];
}
[self setNeedsDisplay];
}

下載管理類下載函數(shù)

- (void)downloadImageWithURLString:(NSString *)urlStr
{
// 1.判斷內(nèi)存緩存 {urlStr: image}
UIImage *cacheImage = [self.imageCache objectForKey:urlStr];
if (cacheImage != nil)
{
//發(fā)出下載完成的通知,并傳回urlStr和圖片
[self postDownloadCompleteNotification:urlStr withImage:cacheImage];
return;
}
// 2.判斷沙盒緩存
NSString *cacheImagePath = [self cacheImagePathWithURLString:urlStr];
cacheImage = [UIImage imageWithContentsOfFile:cacheImagePath];
if (cacheImage != nil)
{
// 從沙盒中讀取到了圖片,設(shè)置到內(nèi)存緩存中,方便下次可以直接從內(nèi)存中讀取
[self.imageCache setObject:cacheImage forKey:urlStr];
// 返回圖片
[self postDownloadCompleteNotification:urlStr withImage:cacheImage];
return;
}
// 3.判斷操作緩存,防止圖片多次下載 {urlStr: operation}
if (self.operationCache[urlStr] != nil)
{
// 有操作正在下載這張圖片
NSLog(@"有操作正在下載這張圖片");
return;
}
// 1.定義下載圖片操作
SQDownloadOperation *downloadOperation = [SQDownloadOperation downloadOperationWithURLString:urlStr cacheImagePath:cacheImagePath];
// 設(shè)置操作下載完成的回調(diào),當(dāng) downloadOperation 的 main 方法執(zhí)行完成的時(shí)候回調(diào)用
__weak typeof(downloadOperation) weakDownloadOperation = downloadOperation;
downloadOperation.completionBlock = ^() {
// 1. 獲取下載完成的圖像
UIImage *image = [weakDownloadOperation getDownloadImage];
// 2. 從操作緩沖池中刪除操作
[self.operationCache removeObjectForKey:urlStr];
// 3. 判斷圖像是否為空(縮略圖)
if (image != nil)
{
// 設(shè)置下載的圖片到圖片內(nèi)存緩存中
[self.imageCache setObject:image forKey:urlStr];
// 4. 主線程回調(diào)
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//發(fā)出下載完成通告
[self postDownloadCompleteNotification:urlStr withImage:image];
}];
}
else
{
//如果圖片為空,返回下載失敗時(shí)的默認(rèn)圖片
image = [UIImage imageNamed:@"default.jpg"];
// 4. 主線程回調(diào)
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//發(fā)出下載完成通告
[self postDownloadCompleteNotification:urlStr withImage:image];
}];
}
};
// 2.將下載圖片操作添加到隊(duì)列中
[self.downloadQueue addOperation:downloadOperation];
// 3.將下載圖片操作添加到下載操作緩存中
[self.operationCache setObject:downloadOperation forKey:urlStr];
}
- (void)postDownloadCompleteNotification:(NSString *)urlStr withImage:(UIImage *)image
{
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:urlStr, @"urlStr", image, @"image",nil];
[[NSNotificationCenter defaultCenter]postNotificationName:NOTIFICATION_DOWNLOAD_CALLBACK
object:nil
userInfo:dic];
}

控制器中使用

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
SQPhotoCell *cell = (SQPhotoCell *)[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier
forIndexPath:indexPath];
UIImage *placeholder = [UIImage imageNamed:@"gray.jpg"];
NSString *imageUrl = @"http://www.taopic.com/uploads/allimg/110925/9117-11092509545328.jpg";
[cell setImageWithURL:imageUrl placeholder:placeholder];
return cell;
}

寫在后面

這個(gè)異步下載圖片的思路是仿照SDWebImage的,雖然可以直接看到源碼,也有一些文章和博客講解思路,但自己在沒有接觸過多線程編程的情況下學(xué)習(xí)這個(gè)下載思路還是花了挺多時(shí)間的。前期一直都有些著急,想要趕緊做出來,在對(duì)好多東西都是懵懵懂懂的情況下就去做了,后來才慢慢意識(shí)到,其實(shí)慢就是快,慢下來,把問題想清楚了再去實(shí)施雖然前期感覺是不太好的,但到越到后面就越能發(fā)現(xiàn)這種慢的好處。

相關(guān)文章

最新評(píng)論