填充tableview与相机胶卷图像

问题描述:

我想从tableview中的相机胶卷填充图像。我创建一个资产组。填充tableview与相机胶卷图像

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 
self.tableView.delegate = self; 
self.tableView.dataSource = self; 

self.assetsLibrary = [[ALAssetsLibrary alloc] init]; 
[self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) { 
    if(nil!=group){ 
     [group setAssetsFilter:[ALAssetsFilter allPhotos]]; 
     self.assetGroup = group; 
     NSLog(@"%d images found", self.assetGroup.numberOfAssets); 
    } 
} failureBlock:^(NSError *error) { 
    NSLog(@"block fucked!"); 
}]; 
[self.tableView reloadData]; 

} 

CellForRowAtIndexPath,我使用GCD背景队列各自索引处,以用图像的细胞。

static NSString *CellIdentifier = @"Cell"; 

    dispatch_queue_t imgLoadQueue = dispatch_queue_create("Thumb loader", NULL); 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

} 

dispatch_async(imgLoadQueue, ^{ 
    [self.assetGroup enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:indexPath.row] options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { 
     if (nil != result) { 
      ALAssetRepresentation *repr = [result defaultRepresentation]; 
      UIImage *img = [UIImage imageWithCGImage:[repr fullResolutionImage]]; 
      cell.imageView.image = img; 

     } 
    }]; 

}); 


return cell; 

问题是,初始单元格是空的。图像只有在我开始滚动后才开始加载。而且,一旦我滚动,应用程序就会崩溃。我对GCD相当陌生,似乎没有正确使用它。对此事的任何帮助表示赞赏。在你的cellForRowAtIndexPath方法

+1

“应用程序崩溃”是一个非常糟糕的解释。你能提供崩溃日志和错误信息吗?你的应用程序可能会由于许多不同的原因而崩溃。 –

+0

您的代码存在一些错误,但在此之前 - 您确定Assets库是线程安全的吗? – Mar0ux

+0

'@property(nonatomic,readwrite)ALAssetsLibrary * assetsLibrary;'和 '@property(nonatomic,readwrite)ALAssetsGroup * assetGroup;' – CalZone

您需要在viewDidLoad中的枚举块完成并且已填充self.assetGroup之后调用[self.tableView reloadData]。枚举块是异步执行的,因此在块完成之前调用reloadData并在表视图中委托回调您的assetGroup不包含任何数据。当你开始滚动时,该属性被填充,你开始看到图像。

我还没有看到解释如何检测枚举块结束的苹果文档,但这两个接受的答案表明,枚举结束时,组值将为零。

iPhone enumerateGroupsWithTypes finishing selector Find out when my asynchronous call is finished

所以把一个else条件在组枚举块 -

if(nil!=group){ 
    [group setAssetsFilter:[ALAssetsFilter allPhotos]]; 
    self.assetGroup = group; 
    NSLog(@"%d images found", self.assetGroup.numberOfAssets); 
} 
else 
    [self.tableView reloadData]; 

取出reloadData枚举块之后被调用。

尝试将CellForRowAtIndexPath中的枚举块取出GCD队列。该块也将异步执行。无需将其分派到后台队列。

+0

Freaking真棒!谢谢你的朋友。那正是我的问题。 – CalZone

+0

嘿凯达,我仍然得到记忆警告,任何想法如何解决? – CalZone

+0

你在控制台中看到警告信息吗?或者是didReceiveMemoryWarning被调用。 – Kedar

更改行从:

cell.imageView.image = img; 

到:

dispatch_async(dispatch_get_main_queue(), ^{ 
    cell.imageView.image = img; 
}); 

在视图中的每个变化,必须在主线程中实现,如果你在其他线程改变你的细胞图像(什么你目前的做)单元格演示文稿不会改变。

+0

性能稍微好一些,但单元格没有被加载,它们只在我开始滚动时加载。 – CalZone

+0

设置图像后是否尝试重新加载单元格? [self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade]; – edzio27

+1

你认为这可能是'cellForrowAtIndexPath'在'viewDidload'之前调用的事实吗?因为我在'viewdidload'中创建组,所以它不适用于'cellForRowAtIndexPath' – CalZone