ios UIImageView异步加载网络图片2

时间:2021-07-02 07:32:11
 //1. NSData dataWithContentsOfURL
// [self.icon setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:tempUrl]]]; //2. dispath形式添加到异步处理
// [self imageDownLoadByUrlASYNC:tempUrl Complete:^(UIImage *image) {
// [self.icon setImage:image];
// }];
//3. 当前我所选用的方式 边下载边加载的方式 用的CGImageRef imageWithCGImage
_request = [[NSURLRequest alloc] initWithURL:tempUrl];
_conn = [[NSURLConnection alloc] initWithRequest:_request delegate:self]; _incrementallyImgSource = CGImageSourceCreateIncremental(NULL); _recieveData = [[NSMutableData alloc] init];
_isLoadFinished = false; self.icon.alpha = .5;
self.lblTitle.alpha = .5;
[self.lblTitle setText:appName];

第一种方式,是基本上很少有人用的 是最基础的方式 这种方式有个问题 就是网络不好的情况下会卡主线程,导致程序假死

第二种方式,请款这段实现代码

//
//-(void)imageDownLoadByUrlASYNC:(NSURL *)url Complete:(complete)finished
//{
// //异步并列执行
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// UIImage *image = nil;
// NSError *error;
// NSData *responseData = [NSData dataWithContentsOfURL:url options:NSDataReadingMappedIfSafe error:&error];
// image = [UIImage imageWithData:responseData];
// //跳回主队列执行
// dispatch_async(dispatch_get_main_queue(), ^{
// //在主队列中进行ui操作
// finished(image);
// });
//
// });
//}

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

NSError *error;

UIImage *image = nil;

SDWebImageManager *manager = [SDWebImageManager sharedManager];

BOOL existBool = [manager diskImageExistsForURL:url];//判断是否有缓存

if (existBool) {

image = [[manager imageCache] imageFromDiskCacheForKey:url.absoluteString];

}else{

NSData *responseData = [NSData dataWithContentsOfURL:url options:NSDataReadingMappedIfSafe error:&error];

image = [UIImage imageWithData:responseData];

}

//跳回主队列执行

dispatch_async(dispatch_get_main_queue(), ^{

//在主队列中进行ui操作

__block CGFloat itemW = mWidth;

__block CGFloat itemH = 0;

NSLog(@"%f",image.size.width);

//根据image的比例来设置高度

if (image.size.width) {

itemH = image.size.height / image.size.width * itemW;

if (itemH >= itemW) {

if (itemH >= mHeight-64) {

NSLog(@"%f",[UIScreen mainScreen].bounds.size.width);

UIScrollView *sv = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 64, itemW, mHeight-64)];

sv.contentSize = CGSizeMake(itemW, itemH);

sv.showsVerticalScrollIndicator = NO;

sv.userInteractionEnabled = YES;

[self.view addSubview:sv];

imageView.frame = CGRectMake(0, 0, itemW, itemH);

imageView.contentMode = UIViewContentModeScaleAspectFit;

[sv addSubview:imageView];

}else{

imageView.frame = CGRectMake(0, 64, itemW, itemH);

imageView.contentMode = UIViewContentModeScaleAspectFit;

[self.view addSubview:imageView];

}

}else{

imageView.frame = CGRectMake(0, 64, itemW, itemH);

imageView.contentMode = UIViewContentModeScaleAspectFit;

[self.view addSubview:imageView];

}

}else{

imageView.frame = CGRectMake(0, 64, mWidth, mHeight-64);

imageView.contentMode = UIViewContentModeScaleAspectFit;

[self.view addSubview:imageView];

}

[self.myView stopAnimating];

});

});

虽然情况跟第一种实现一样,但是将执行代码添加到对应的异步执行中 然后再成功下载之后 获取到image之后 放到主线程执行回调 设置image

第三种方式 需要以下代码 这是我百度到的方式

#pragma mark -- NSURLConnectionDataDelegate

-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
_expectedLeght=response.expectedContentLength;
NSLog(@"expectedLength:%lld",_expectedLeght); NSString*mimeType=response.MIMEType;
NSLog(@"MIMETYPE%@",mimeType); NSArray*arr=[mimeType componentsSeparatedByString:@"/"];
if(arr.count<1||![[arr objectAtIndex:0] isEqual:@"image"])
{
NSLog(@"notaimageurl");
[connection cancel];
_conn=nil;
}
}
-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(@"Connection%@error,errorinfo:%@",connection,error);
}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(@"ConnectionLoadingFinished!!!");
//ifdownloadimagedatanotcomplete,createfinalimage
if(!_isLoadFinished){
CGImageSourceUpdateData(_incrementallyImgSource,(CFDataRef)_recieveData,_isLoadFinished);
CGImageRef imageRef=CGImageSourceCreateImageAtIndex(_incrementallyImgSource,0,NULL);
UIImage * image=[UIImage imageWithCGImage:imageRef];
[self.icon setImage:image];
CGImageRelease(imageRef);
}
}
-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
[_recieveData appendData:data]; _isLoadFinished=false;if(_expectedLeght==_recieveData.length){
_isLoadFinished=true;
} CGImageSourceUpdateData(_incrementallyImgSource,(CFDataRef)_recieveData,_isLoadFinished);
CGImageRef imageRef=CGImageSourceCreateImageAtIndex(_incrementallyImgSource,0,NULL);
UIImage * image=[UIImage imageWithCGImage:imageRef];
[self.icon setImage:image];
CGImageRelease(imageRef);
}

这个方法经过我测试了 非常好用 但是不知道会不会有什么bug 只是刚使用 并且用户体验也会相应增加