1

グランドセントラルディスパッチャを使用してサーバーから画像をロードしていますが、テーブルをスクロールすると、データ、つまり画像がごちゃごちゃになります-最初の画像が他の場所に来て、他の画像もそうであることを意味します。

- (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;
}
4

1 に答える 1

2

これは、非同期メソッドが終了するまでに、cellリサイクルされて別のインデックスパスに使用されているため、間違ったセルを更新しているためです。

更新の時点で、テーブルビューの(データソースメソッドではない)cellForRowAtIndexPath:メソッドを使用してセル参照を取得します。これにより、正しいセルが返されます。セルが画面に表示されなくなった場合は、nilが返されます。このセルは安全に更新できます。

繰り返しダウンロードしないように、モデルにも画像データを追加する必要があります。

例として、この行の代わりに:

[cell.contentView addSubview:userImageButton];

次のようなものが必要です。

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

コードにはさらに問題があります。画像をキャッシュしていない場合は、このセルが画面に表示されるたびにこのサブビューを追加します。セルがボタンを必要としない場合に再利用される場合、ボタンは引き続き存在します。私はあなたの質問で説明されているように「GCDジャンブリング」にのみ対処しました。

于 2013-03-06T07:39:35.193 に答える