objective-c - enumerateGroupsWithTypes 在主线程中轮询时不会执行 block

标签 objective-c ios objective-c-blocks alasset alassetslibrary

在 iOS 4.x 上,我尝试枚举设备上的所有照片,当枚举完成后,再用相同的方法进一步处理该列表。

由于 enumerateGroupsWithTypes 的 block 在另一个线程上异步运行,我看不到如何阻止主线程继续执行,我的解决方案是轮询我正在收集的照片数组,以防止进一步处理开始直到准备就绪直到它看到它已经通过在末尾包含一个 NSNull 对象来完成填充。

在 iOS 4.0 上它工作正常——当另一个线程枚举照片时轮询继续进行,然后在完成后在主线程上继续执行。在 iOS 4.1+ 上,轮询是如何阻止另一个线程执行它的任何 block ,从而使轮询陷入无限循环。

除了通过将进一步处理分解为枚举 block 可以调用的不同方法来接受枚举的异步性质之外,是否有更好的方法来实现这一目标?

加分项:为什么我的轮询方法适用于 4.0 而不是 4.1+?

NSMutableArray *photos = [NSMutableArray new];

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
    if(result != NULL) {
        [photos addObject:result];
    }
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
    if(group != nil)
        [group enumerateAssetsUsingBlock:assetEnumerator];
    else
        [photos addObject:[NSNull null]];
};

ALAssetsLibrary *library = [ALAssetsLibrary new];

[library enumerateGroupsWithTypes:ALAssetsGroupAll
                       usingBlock:assetGroupEnumerator
                     failureBlock:^(NSError *error) {
                         NSLog(@"%@", error);
                     }];

// keep polling until the photos have all been enumerated
// (NSNull is the last 'photo' added)
while (![photos count] || ![[photos objectAtIndex:[photos count]-1] isEqual:[NSNull null]]);

// ... further processing ...

最佳答案

更好的方法是让您的 block 开始进一步处理(例如使用 performSelectorOnMainThread:withObject:waitUntilDone: ),而不是让您的主线程为其轮询。

我不能确定为什么它在 4.0 中有效而在 4.1 中失败。在 4.1 中它可能在某些情况下不再是异步的(例如,当用户不需要被提示时),或者在 4.1 中它在启动后台任务之前等待主线程上的回调,或者在你的4.1 设备或模拟器实例它试图请求许可(并挂断,因为你有主运行循环被阻止)并且如果你没有在你之前的测试中已经授权它访问照片库,也会在 4.0 上失败。

关于objective-c - enumerateGroupsWithTypes 在主线程中轮询时不会执行 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6409656/

相关文章:

objective-c - 使用 ios5 在 iPad 应用程序上测试互联网连接

objective-c - 如何从 NSWindow 对象创建 NSTouchBar?

objective-c - EXC_BAD_ACCESS 调用 block

ios - Objective-C try-catch - 为什么编译?为什么返回不同的构建调试与发布?

iphone - 使用字符串的值来确定类的实例

objective-c - 在 UITabBar 应用程序中旋转一个 UIViewController

ios - 多个 TableViewController 和 Segues

ios - 自动布局 : empty UITextField is only wide enough for 1 character

ios - 使用 PKRevealController 时在前 View 上推送新 View

ios - 使用 block 语句检测失败的文件修改