0

我有一个 ImageDownloader 类,它具有使用 GCD 下载图像的功能:

- (void) downloadImageFromURL:(NSURL *) url completionBlock:(void (^)(UIImage *image, NSError *error)) block {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul), ^{
    NSData *imageData = [NSData dataWithContentsOfURL:url];
    UIImage *picture=[UIImage imageWithData:imageData];
    if(picture) {
        block(picture, nil);
    } 
    else {
        NSError *error = [NSError errorWithDomain:@"image_download_error" code:1 
                                         userInfo:[NSDictionary dictionaryWithObject:@"Can't fetch data" forKey:NSLocalizedDescriptionKey]];
        block(nil, error);
    }

  });
}

我的 tableviewcell(在它自己的 nib 文件中定义)为每一行调用这个函数,如下所示:

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

//custom cell in nib file
static NSString *MyIdentifier = @"contactsCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"contactsCell" owner:self options:nil]; //feedCell je ime nib fajla
    cell = contactsCell;
    self.contactsCell = nil;
}  

if (indexPath.section == 0) {
    UIImageView *avatar=(UIImageView *) [cell viewWithTag:1];
    avatar.image=[UIImage imageNamed:@"petek.jpg"];
    UILabel *nameLabel= (UILabel *) [cell viewWithTag:2];
    nameLabel.text=@"Some guy";
    UIButton *askBtn=(UIButton *) [cell viewWithTag:3];
    [askBtn setTitle:@"Ask" forState:UIControlStateNormal];
    [askBtn addTarget:self action:@selector(checkButtonTapped:event:)  forControlEvents:UIControlEventTouchUpInside];

}
else {
    UIImageView *avatar=(UIImageView *) [cell viewWithTag:1];
    ImageDownloader *idl=[[ImageDownloader alloc] init];
    NSURL *imageUrl=[NSURL URLWithString:@"http://someImageUrl"];
    [idl downloadImageFromURL:imageUrl completionBlock:^(UIImage *image, NSError *error)
     {
         if(!error) {
             dispatch_sync(dispatch_get_main_queue(), ^(void) {
                 avatar.image=image;
             });
         } else {
             NSLog(@"error %@", error);
         }

     }];
    UILabel *nameLabel= (UILabel *) [cell viewWithTag:2];
    nameLabel.text=@"John Stockton";
    UIButton *followBtn=(UIButton *) [cell viewWithTag:3];
    [followBtn setTitle:@"Follow" forState:UIControlStateNormal];
    [followBtn addTarget:self action:@selector(checkButtonTapped:event:)  forControlEvents:UIControlEventTouchUpInside];

}

    return cell;    

}

第 1 部分的图像正确加载,但在滚动时,有时第 1 部分的一行中的图像仅在片刻之内有第 0 部分的图像。

我究竟做错了什么?

4

3 回答 3

1

如果您avatar.image = nil在开始下载之前这样做,您将不会遇到此问题。发生这种情况是因为单元格出现在屏幕上与单元格的图像完成下载之间存在延迟。

于 2012-07-03T12:47:33.280 回答
1

当您重用名为 的行的唯一标识符时MyIdentifier,它可能会使旧行的图像出队,然后重新加载数据。

如果静态标识符如:

NSString *MyIdentifier = [NSString stringWithFormat:@"contactsCell-%d-%d",indexPath.section,indexPath.row];
于 2012-07-03T12:51:20.187 回答
0

UIImageView *avatar=(UIImageView *) [cell viewWithTag:1]; 永远不要在细胞中携带任何信息。它们是可重复使用的。

于 2012-07-03T12:52:40.373 回答