iOS - 从块返回变量

时间:2012-09-27 21:11:42

标签: iphone objective-c ios alassetslibrary

我有一个iOS项目,它从数据源方法中提取图像。我希望能够从assets library中提取图像(下面的代码块就可以了)。

但是,我需要使用此dataSource方法返回UIImage,但是当我使用资源库方法获取图像时,图像将返回到结果块中。简单地将return image放在结果块中显然不起作用。

有没有人知道如何让方法从结果块中返回UIImage?我已经看到了几个关于在块内返回图像的其他问题,但是他们说要调用另一种方法。我 - 不幸的是 - 不能这样做,因为这个方法是一个必须返回UIImage的nimbus数据源方法。

非常感谢任何帮助或建议!代码如下:

- (UIImage *)photoAlbumScrollView: (NIPhotoAlbumScrollView *)photoAlbumScrollView
                     photoAtIndex: (NSInteger)photoIndex
                        photoSize: (NIPhotoScrollViewPhotoSize *)photoSize
                        isLoading: (BOOL *)isLoading
          originalPhotoDimensions: (CGSize *)originalPhotoDimensions {

    __block UIImage *image = nil;
    ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
    [assetslibrary assetForURL:[_photos objectAtIndex:photoIndex]
                   resultBlock:^(ALAsset *asset){
                       ALAssetRepresentation *rep = [asset defaultRepresentation];
                       CGImageRef imageRef = [rep fullScreenImage];
                       if (imageRef) {
                           image = [UIImage imageWithCGImage:imageRef];

                       }

                   }
                  failureBlock:^(NSError *error) {
                      //return nil;
                  }];

    return image;
}

2 个答案:

答案 0 :(得分:2)

您应该为每个图像创建一个数组。首次调用此数据源方法时,您将不会在该数组中拥有该索引的图像。启动资产调用然后返回占位符图像。当块返回时,将占位符图像替换为块中返回的资产图像。您可能需要使用GCD在主队列上执行此操作。

答案 1 :(得分:0)

所以我认为我有解决方案。我们的想法是使用dispatch_group,因为您可以等待一个调度组 - 它为您提供了一种阻止线程直到某些事情发生的方法。可能需要您的数据源操作不使用mainthread,但您将不得不使用它。让我们假设实现photoAlbumScrollView的对象称为'obj'。

  • obj创建一个串行调度队列(称为队列)
  • datasource发送[obj photoAlbumScrollView]消息
  • photoAlbumScrollView执行它现在所做的工作,但在返回队列等待之前
  • 最后一个块取消阻止让小组完成的队列

代码:

__block UIImage *image = nil;
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];

dispatch_queue_t queue = dispatch_queue_create("com.myApp.assetFetch", DISPATCH_QUEUE_SERIAL);

[assetslibrary assetForURL:[_photos objectAtIndex:photoIndex]
               resultBlock:^(ALAsset *asset){
                   ALAssetRepresentation *rep = [asset defaultRepresentation];
                   CGImageRef imageRef = [rep fullScreenImage];
                   if (imageRef) {
                       image = [UIImage imageWithCGImage:imageRef];
                   }
                   dispatch_resume(queue);
               }
              failureBlock:^(NSError *error) {
                   dispatch_resume(queue);
              }];
dispatch_suspend(queue);
dispatch_sync(queue, ^{ NSLog(@"UNSUSPEND!"); }); // ultimately a block with just a ';' in it
dispatch_release(queue);

return image;

我显然没有对此进行测试,但它或它附近的东西应该可以工作,再假设你可以在一个线程而不是mainThread上创建它。