ios UIImageView异步加载网络图片2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //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]; |
第一种方式,是基本上很少有人用的 是最基础的方式 这种方式有个问题 就是网络不好的情况下会卡主线程,导致程序假死
第二种方式,请款这段实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // //-(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); // }); // // }); //}<br><br><br> |
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
第三种方式 需要以下代码 这是我百度到的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #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 只是刚使用 并且用户体验也会相应增加
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?