首页 技术 正文
技术 2022年11月19日
0 收藏 763 点赞 3,230 浏览 5763 个字

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

NSURL *url = [NSURL URLWithString: detailedActivity.pictures];

NSData *data = [[NSData alloc] initWithContentsOfURL:url];

dispatch_async(dispatch_get_main_queue(), ^(void){

self.activityImageView.image = [[UIImage alloc]initWithData:data];

});

});

本文转载至 http://stackoverflow.com/questions/16663618/async-image-loading-from-url-inside-a-uitableview-cell-image-changes-to-wrong

uiimageview 异步加载图片

favorite

34

I’ve written two ways to async load pictures inside my UITableView cell. In both cases the image will load fine but when I’ll scroll the table the images will change a few times until the scroll will end and the image will go back to the right image. I have no idea why this is happening.

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString:
@"http://myurl.com/getMovies.php"]];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}-(void)fetchedData:(NSData *)data
{
NSError* error;
myJson = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
[_myTableView reloadData];
} - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
// Usually the number of items in your array (the one that holds your list)
NSLog(@"myJson count: %d",[myJson count]);
return [myJson count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
} dispatch_async(kBgQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]]]; dispatch_async(dispatch_get_main_queue(), ^{
cell.poster.image = [UIImage imageWithData:imgData];
});
});
return cell;
}

… …

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{            myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell == nil) {
cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]];
NSURLRequest* request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
cell.poster.image = [UIImage imageWithData:data];
// do whatever you want with image
} }];
return cell;
}

ios objective-c cocoa-touch uitableview

shareimprove this question edited Jan 12 ’14 at 9:16uiimageview 异步加载图片Wil Shipley
5,9661336
asked May 21 ’13 at 6:36uiimageview 异步加载图片Segev
8,99262982
 
3  
You’re trying to store information in the actual cells. This is bad, very bad. You should store information in n array (or something similar) and then display it in the cells. The information in this case is the actual UIImage. Yes load it asynchronously but load it into an array. –  Fogmeister May 21 ’13 at 7:00
1  
@Fogmeister Are you referring to poster? That’s presumably an imageview in his custom cell, so what EXEC_BAD_ACCESS is doing is perfectly right. You are correct that you should not use the cell as the repository for model data, but I don’t think that’s what he’s doing. He’s just giving the custom cell what it needs to present itself. Furthermore, and this is a more subtle issue, I would be wary about storing an image, itself, in your model array backing your tableview. It’s better to use a image caching mechanism and your model object should retrieve from that cache. –  Rob May 21 ’13 at 14:23
1  
Yes, exactly my point. Looking at the request (which is shown in full) he is downloading the image asynchronously and putting it directly into the imageView in the cell. (Thus using the cell to store the data, i.e. the image). What he should be doing is referencing an object and requesting the image from that object (contained in an array or somewhere). If the object doesn’t yet have the image it should return a placeholder and download the image. Then when the image is downloaded and ready to display let the table know so it can update the cell (if it’s visible). –  Fogmeister May 21 ’13 at 14:28
1  
What he is doing will force the download every single time he scrolls to that cell in the table. Whether the images are stored persistently is up to him, but at least store them for the life time of the tableview. – Fogmeister May 21 ’13 at 14:28 
1  
Exactly 😀 That way you only need to fetch the image from the URL once. You will see this on things like Facebook Friend Picker. When you start it all the avatars are grey placeholders. Then as you scroll they all fill in as it moves along. But then when you scroll back to a cell previously shown it will instantly show the already downloaded image. –  Fogmeister May 21 ’13 at 14:41

show 4 more comments

7 Answers

activeoldestvotes       

shareimprove this answer edited Feb 10 ’14 at 3:39   answered May 21 ’13 at 6:47uiimageview 异步加载图片Rob
120k12183285
 
    
Thanks. I believe you need to edit your answer. updateCell.poster.image = nil tocell.poster.image = nil; updateCell is called before it’s declared. –  Segev May 21 ’13 at 7:09
    
@EXEC_BAD_ACCESS quite right. Thanks. –  Rob May 21 ’13 at 7:11
    
@EXEC_BAD_ACCESS AFNetworking is a general networking class that eliminates a lot of uglyNSURLConnection programming. SDWebImage is a smaller framework, focusing primarily on images being retrieved from the web. Both do a pretty good job on their UIImageView categories. –  Rob May 21 ’13 at 7:30 
3  
@Rob At this moment, I love you more than I love my girlfriend, I don’t have one but I’m sure I would love you more than her if thats the case, I had this stupid issue for a month now, and i’m delaying it everytime, but thanks to you NO MORE DELAYING! I fixed it! Make sure to get my app, maybe in less than a week, its called Feelit, we would be happy to have you aboard! xD –  Albara Sep 15 ’13 at 13:31 
2  
This is one of the most beautiful solutions so far! Thanks! –  jovanjovanovic Feb 27 ’14 at 4:00
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,983
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,500
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,344
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,127
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,761
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,838