GCD在滚动tableview上混乱数据

时间:2013-03-06 07:06:58

标签: ios objective-c uitableview

我正在使用盛大的中央调度员从服务器加载图像但是当我滚动表格时,数据,即图像,混乱 - 意味着第一张图像来到其他地方,就像明智的其他图像一样。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"ItemImageCellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
        cell.selectionStyle=UITableViewCellSelectionStyleNone;

    }

    NSDictionary *item=[responseDictionary objectAtIndex:[indexPath row]];


    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);


    NSString *actionForUser=[item objectForKey:@"action"];



    objc_setAssociatedObject(cell,
                             kIndexPathAssociationKey,
                             indexPath,
                             OBJC_ASSOCIATION_RETAIN);

    dispatch_async(queue, ^{

        if([actionForUser isEqualToString:like])
        {
            NSURL *url = [NSURL URLWithString:[item objectForKey:@"user_image"]];
            NSData *data1 = [[NSData alloc] initWithContentsOfURL:url];
            UIImage *image1 = [[UIImage alloc] initWithData:data1];

            //userProfileimage
            UIButton *userImageButton = [[UIButton alloc] initWithFrame:CGRectMake(10,5, 40,40)];
            userImageButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
            userImageButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
            [userImageButton setBackgroundImage:image1 forState:UIControlStateNormal];
            [userImageButton addTarget:self
                            action:@selector(userImageButtonclick:)
                  forControlEvents:UIControlEventTouchDown];
            [cell.contentView addSubview:userImageButton];

        }
    });
    return cell;
}

1 个答案:

答案 0 :(得分:2)

这是因为当您的异步方法完成时,cell已被回收并用于不同的索引路径,因此您正在更新错误的单元格。

在更新时,使用 tableview的(不是数据源方法)cellForRowAtIndexPath:方法获取单元格引用。这将返回正确的单元格,如果单元格不再出现在屏幕上,则返回nil。您可以安全地更新此单元格。

您可能应该将图像数据添加到模型中,这样您就不会重复下载它。

作为一个例子,而不是这一行:

[cell.contentView addSubview:userImageButton];

你应该有这样的东西:

UITableViewCell *cellToUpdate = [tableView cellForRowAtIndexPath:indexPath];
[cellToUpdate.contentView addSubview:userImageButton];

您的代码还有其他问题;如果您没有缓存图像,则每次将此单元格显示在屏幕上时,您将添加此子视图,如果单元格在不需要按钮的情况下重复使用,则该按钮仍将存在。我只解决了你问题中描述的“GCD jumbling”。