使用相机胶卷图像填充tableview

时间:2013-06-01 13:46:03

标签: ios uitableview grand-central-dispatch camera-roll

我正试图在桌面视图中填充相机胶卷中的图像。

ViewDidLoad中,我创建了一个资产组。

- (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的新手,似乎没有正确使用它。感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

更改cellforRowAtIndexPath方法中的行:

cell.imageView.image = img;

为:

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

视图中的每个更改都必须在主线程中实现,如果您在其他线程中更改单元格图像(您当前所做的)单元格表示不会更改。

答案 1 :(得分:2)

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

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

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队列中取出。该块也将异步执行。无需将其发送到后台队列。