iOS-UIImageView載入網路下載的圖片(非同步+多線程)
最原始的載入網路下載的圖片方式:
//最原始載入網狀圖片方法,相當阻塞主線程,介面卡頓-(void)setImageWithURL:(NSString *)imageDownloadUrl{ UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(44, 64, 250, 250)]; NSURL *URL = [NSURL URLWithString:imageDownloadUrl]; NSError *ERROR; NSData *imageData = [NSData dataWithContentsOfURL:URL options:NSDataReadingMappedIfSafe error:&ERROR]; UIImage *image = [UIImage imageWithData:imageData]; [imageView setImage:image];}
使用非同步線程載入圖片,在載入完成後設定圖片,可以在網路載入完成之前,UIimageview先使用佔位圖片。
//非同步線程載入網路下載圖片 ——> 回到主線程更新UI-(void)downloadImageWithUrl:(NSString *)imageDownloadURLStr{ //以便在block中使用 __block UIImage *image = [[UIImage alloc] init]; //圖片下載連結 NSURL *imageDownloadURL = [NSURL URLWithString:imageDownloadURLStr]; //將圖片下載在非同步線程進行 //建立非同步線程執行隊列 dispatch_queue_t asynchronousQueue = dispatch_queue_create("imageDownloadQueue", NULL); //建立非同步線程 dispatch_async(asynchronousQueue, ^{ //網路下載圖片 NSData格式 NSError *error; NSData *imageData = [NSData dataWithContentsOfURL:imageDownloadURL options:NSDataReadingMappedIfSafe error:&error]; if (imageData) { image = [UIImage imageWithData:imageData]; } //回到主線程更新UI dispatch_async(dispatch_get_main_queue(), ^{ [_imageView setImage:image]; }); });}
如果考慮到安全執行緒,需要開啟自動釋放池,此方法同上:
#pragma mark - 下載圖片-子線程調用-(void)downloadImage{ /** 子線程裡面的runloop預設不開啟,也就意味著不會自動建立自動釋放池,子線程裡面autorelease的對象 就會沒有池子釋放。也就一位置偶棉沒有辦法進行釋放造成記憶體泄露 所以需要手動建立 */ @autoreleasepool { NSLog(@"%@",[NSThread currentThread]); NSURL *url = [NSURL URLWithString:@"http://baidu.com/image/Users/qiuxuewei/Desktop/qiu.JPG"]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image0 = [UIImage imageWithData:data]; UIImage *image = [UIImage imageNamed:@"qiu.JPG"]; //UI要求在主線程中進行 //self.imageView.image = image; //1、 [self performSelectorOnMainThread:@selector(updataImage:) withObject:image waitUntilDone:NO]; //2、 [self performSelector:@selector(updataImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES]; [self.imageView performSelectorOnMainThread:@selector(updataImage:) withObject:image waitUntilDone:YES]; //waitUntilDone: 表示是否等待子線程方法執行完畢 //如果是YES:那就等子線程方法執行完再執行當前函數 NSLog(@"完成.."); }}-(void)updataImage:(UIImage *)image{ self.imageView.image = image;}