0

I have a UITableView that populates its cells with thumbnail images. In my case, the thumbnails are downloaded from a server. My code is as follows:

if (![self thumbnailExists])
{
    self.thumbnailImageView.image = nil;
    [self.activityIndicatorView startAnimating];

    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:
    ^{
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.thumbnailURL]];
        UIImage *image = [UIImage imageWithData:data];


        [[NSOperationQueue mainQueue] addOperationWithBlock:
         ^{
             SubmenuScrollViewTableViewCell *submenuScrollViewTableViewCell = (SubmenuScrollViewTableViewCell*)[(UITableView*)self.superview cellForRowAtIndexPath:self.indexPath];
             [submenuScrollViewTableViewCell.activityIndicatorView stopAnimating];
             submenuScrollViewTableViewCell.thumbnailImageView.image = image;
         }];
    }];

    [self.operationQueue addOperation:operation];
    [self.operationQueues setObject:operation forKey:[self title]];
}

This code is based on the great WWDC2012 presentation: "Building Concurrent User Interfaces on iOS". The main difference between my code and the code in the presentation is I'm populating my cells with data that is retrieved from the web.

It works well for the most part, but the problem I'm having is if I scroll really fast, then one of the cells might show up with the wrong thumbnail (usually I noticed said cell would be a multiple of the cell from which the thumbnail belongs to). I should mention this code is being executed in the layoutSubviews method of an overridden UITableViewCell.

Can anyone spot any flaws in this code?

4

2 に答える 2

1

コードが壊れている理由は、次のコード行のためです。

 SubmenuScrollViewTableViewCell *submenuScrollViewTableViewCell = (SubmenuScrollViewTableViewCell*)[(UITableView*)self.superview cellForRowAtIndexPath:self.indexPath];

これが呼び出されたときにインデックス パスでセルを取得し、セルが再利用されるときにこのインデックス パスにあるセルに配置します。これにより、ビューが非常に速く移動し、おそらくサーバーからの応答が別の時間に来る場合に、別のセルに別の画像が配置されます。

prepareForReuse で操作をキャンセルし、セル イメージを消去して、イメージが間違ったセルに配置されたり、イメージが再利用されたりしないようにしてください。

また、一般に、セル自体から tableView を呼び出すことはお勧めできません。

于 2013-08-31T01:47:44.127 に答える
0

この問題は、上記のコードが、私が作成したサブクラス化された UITableViewCell の layoutSubviews メソッドにあったという事実に関係していました。cellForRowAtIndexPath メソッドに戻すと、問題は解消されました。

于 2013-09-03T00:32:53.713 に答える