ios - 用相机胶卷图像填充桌面 View

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

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

ViewDidLoad中,我创建了一个 Assets 组。

- (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 还很陌生,似乎没有正确使用它。感谢任何有关此事的帮助。

最佳答案

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

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

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

因此,在您的组枚举 block 中放置一个 else 条件 -

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

删除在枚举 block 之后调用的 reloadData。

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

关于ios - 用相机胶卷图像填充桌面 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16873370/

相关文章:

ios - UISplitViewController - 从细节更新主 TableView

ios - 使用 UIImagePickerController 拍照后将我发送到详细 View

iphone - 通过 NSURL 和 NSData 传递特殊字符

ios - UITableView 在滚动后将单元格内容放在错误的行上

ios - 如何在 Swift 中的 HeightForRowAt 函数中设置 UITableViewCell 的大小后调整其大小?

ios - 转义闭包捕获非转义参数 'completion' (Swift 5)

objective-c - 哪个更容易使用? GCD 还是 NSOperation?

ios - dispatch_after 错误 : '[AnyObject]?' is not a subtype of 'Void'

ios - 使用 Swift 闭包捕获变量

ios - AJAX 服务被 Google 屏蔽了吗?