2012-08-09 56 views
1

我环顾了SO和网页,并没有找到具体的答案。使用块在表格中加载图像 - dispatch_async返回值

很简单,我有一个表格从Flickr加载图片信息。我想在每个单元格的左侧显示图像的缩略图。

为了做到这一点,而不会阻塞主(UI)线程,我使用的块:

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

    //getting the selected row image 
    NSDictionary* currentImageDictionary=[self.topfifty objectAtIndex:indexPath.row];//topFifty is an array of image dictionaries 


    //creating the download queue 
    dispatch_queue_t downloadQueue=dispatch_queue_create("thumbnailImage", NULL); 

    dispatch_async(downloadQueue, ^{ 

    UIImage *downloadedThumbImage=[self getImage:currentImageDictionary] ; 

    //Need to go back to the main thread since this is UI related 
    dispatch_async(dispatch_get_main_queue(), ^{ 

     cell.imageView.image = downloadedThumbImage ; 

    }); 

    }); 

    dispatch_release(downloadQueue); 

    return cell; 

} 

现在,这是行不通的。因为返回单元格可能会在执行块之前发生。但是与此同时,我不能返回主队列块中的单元格,因为该块不接受返回参数。

我想避免创建一个UITableViewCell子类。

使用块的任何简单的答案?

感谢 九巴

+0

为什么解决方案未被接受?我很确定它的工作原理。 – esh 2013-06-20 04:34:44

回答

4

用做cell.imageView.image = downloadedThumbImage;的问题是,这个小区现在可以重复使用,用于另一行。

相反,你需要更新的具体indexPath当前小区(indexPath将是相同的)

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
cell.imageView.image = image; 

或者有时候我要做的就是更新模型,然后在特定indexPath重装电池:

myModel.image = downloadedThumbImage; 
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
             withRowAnimation:UITableViewRowAnimationNone]; 


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

    //getting the selected row image 
    NSDictionary* currentImageDictionary=[self.topfifty objectAtIndex:indexPath.row];//topFifty is an array of image dictionaries 

    UIImage *currentImage = [currentImageDictionary objectForKey:@"image"]; 

    if (currentImage) { 
     // we already fetched the image, so we just set it to the cell's image view 
     cell.imageView.image = currentImage; 
    } 
    else { 
     // we don't have the image, so we need to fetch it from the server 

     // In the meantime, we can set some place holder image 
     UIImage *palceholderImage = [UIImage imageNamed:@"placeholder.png"]; 
     cell.imageView.image = palceholderImage; 

     // set the placeholder as the current image to your model, so you won't 
     // download the image multiple times (can happen if you reload this cell while 
     // download is in progress) 
     [currentImageDictionary setObject:palceholderImage forKey:@"image"]; 

     // then download the image 
     // creating the download queue 
     dispatch_queue_t downloadQueue=dispatch_queue_create("thumbnailImage", NULL); 

     dispatch_async(downloadQueue, ^{ 
     UIImage *downloadedThumbImage=[self getImage:currentImageDictionary] ; 

     //Need to go back to the main thread since this is UI related 
     dispatch_async(dispatch_get_main_queue(), ^{ 
       // store the downloaded image in your model 
       [currentImageDictionary setObject:image forKey:@"image"]; 

       // update UI 
       UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
       cell.imageView.image = image;  
     }); 
     }); 
     dispatch_release(downloadQueue); 
    } 

    return cell; 
} 
+0

谢谢Eyal.I我仍然在学习块,我认为如果单元格被返回,并且稍后为该单元格执行了块,那么单元格图像将不会被更新(因为我们可能需要重新加载表格)。但我收集了设置单元格图像,甚至在单元格返回后将更新图像(只要它是正确的IndexPath),这就是为什么您使用cellForRowAtIndexPath.Now仍然存在的问题是,当我向下滚动时,它显示前20行图像的下一个“20行”,然后更新它们以获取正确的图像。思考?谢谢 – Spectravideo328 2012-08-09 13:51:22

+0

发生这种情况是因为这些单元格被重用 - 因此它们在imageView属性中已经有了一个图像。你需要存储你已经下载的图像,例如我用键“@ image”将下载的图像添加到图像字典中。这样你可以检查每个单元格,如果你已经有了图像 - 将它设置到单元格imageView,否则下载它并设置其他占位符图像或零图像。看看我更新了我的答案。 – Eyal 2012-08-09 14:44:23

+0

我忘了更新你的模型(图像字典)与下载的图像的代码,检查答案 – Eyal 2012-08-09 15:43:48

相关问题