在表格视图中下载和缓存图像,显示错误的图像

时间:2015-03-07 10:10:09

标签: ios objective-c xcode uitableview

我有一个UITableView,每行包含四个UIButtons来代表用户。我使用Parse.com作为我的数据库。我的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    FriendViewCell *cell = (FriendViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];


    for(int i =0; i<4; i++) {


        if((int)indexPath.row*4+i<[self.currentUser.friends count]) {


            FriendButton *button = cell.buttons[i];
            UILabel *label = cell.labels[i];


            [button setTag:(int)indexPath.row*4+i];
            PFObject *user =self.currentUser.friends[(int)indexPath.row*4+i];
            label.text=user[@"username"];

            UIImage *cachedImage = self.images[user[@"username"]];
            if (cachedImage) {
                //use cached image
                [button setBackgroundImage:cachedImage forState:UIControlStateNormal];
            }

            else {

                //download image
                PFFile *userImageFile = user[@"profilePic"];
                [userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
                    if (!error) {
                        UIImage *image = [UIImage imageWithData:imageData];
                        [self.images setObject:image forKey:user[@"username"]];
                        //this is the line that may be confusing it
                        [button setBackgroundImage:image forState:UIControlStateNormal];
                        //check we have the right number

                        NSLog(@"Number of friends %lu, number of cached images: %lu",(unsigned long)[self.currentUser.friends count], (unsigned long)[self.images count]);

                    }
                }];

            }



        }
}

return cell;

}

我使用NSMutableDictionary来存储图像。如果图像没有在字典中退出,则将使用占位符图像。我的自定义FriendViewCell代码我也有这种方法:

-(void)prepareForReuse {

    //this is called each time we reuse a cell
    UIImage *placeHolder = [UIImage imageNamed:@"placeHolder"];

    //reset placeholder incase we download images
    //Double check this that no images are being double used while loading..
    [self.button1 setBackgroundImage:placeHolder forState:UIControlStateNormal];
    [self.button2 setBackgroundImage:placeHolder forState:UIControlStateNormal];
    [self.button3 setBackgroundImage:placeHolder forState:UIControlStateNormal];
    [self.button4 setBackgroundImage:placeHolder forState:UIControlStateNormal];

}

在检查图像是否在字典中之前,最初设置回占位符。一切正常但我只是注意到,如果我干净安装应用程序并且没有缓存文件,然后尝试加载表,说100个朋友,即许多图像每个按钮图像将不断变化,直到它们是全部下载。我不确定为什么会这样。我可能因为下载图片块中的[button setBackgroundImage:image forState:UIControlStateNormal];而感到沮丧,所以当我滚动时它会混合起来。有人可以给我一些指示吗?

1 个答案:

答案 0 :(得分:0)

所以我解决了这个问题。这可能对其他人有用。我的新下载块是:

//download image
                PFFile *userImageFile = user[@"profilePic"];
                [userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
                    if (!error) {
                        //put the image in the dictionary
                        UIImage *image = [UIImage imageWithData:imageData];
                        [self.images setObject:image forKey:user[@"username"]];
                        NSLog(@"Number of friends %lu, number of cached images: %lu",(unsigned long)[self.currentUser.friends count], (unsigned long)[self.images count]);
                        //fetch the cell again because reuse may have confused it
                        FriendViewCell *originalCell = (FriendViewCell *)[tableView cellForRowAtIndexPath:indexPath];
                        if (originalCell) {
                            FriendButton *button2 = originalCell.buttons[i];
                            [button2 setBackgroundImage:image forState:UIControlStateNormal];
                        }




                    }
                }];

我认为如果在下载后我的理解是正确的,你必须返回并从原始indexPath再次获取单元格,如果你不这样做,它可能会由于单元格重用而将图像发送到错误的单元格。因此,创建一个新的单元格FriendViewCell *originalCell = (FriendViewCell *)[tableView cellForRowAtIndexPath:indexPath],和一个新的UIImageView(在我的情况下是UIButton),然后设置该图像。现在似乎工作得很好,也非常简单。