使用 [ALAssetsLibrary enumerateGroupsWithTypes:] 时的 Cocoa 线程同步
Posted
技术标签:
【中文标题】使用 [ALAssetsLibrary enumerateGroupsWithTypes:] 时的 Cocoa 线程同步【英文标题】:Cocoa thread synchronisation when using [ALAssetsLibrary enumerateGroupsWithTypes:] 【发布时间】:2010-08-27 18:00:29 【问题描述】:我最近和一些人一样,发现 [ALAssetsLibrary enumerateGroupsWithTypes] 喜欢在另一个线程上运行它的块。苹果没有记录这一点真是太可惜了:-)
在我目前的情况下,我需要等待枚举完成,然后主线程返回任何结果。我显然需要某种线程同步。
我已经阅读了有关 NSLock 和 NSConditionLock 的信息,但似乎还没有任何内容符合“通知此工作线程已完成的阻塞线程”的要求。这似乎是一个足够简单的需求 - 谁能指出我正确的方向?
一如既往地欢迎您的提示和嘘声,
M.
【问题讨论】:
【参考方案1】:框架不会在单独的线程上运行这些块。它只是在同一个运行循环中将它们作为附加事件运行。为了证明这一点,试试这个
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:[^(ALAssetsGroup * group, BOOL * stop)
if([NSThread isMainThread])
NSLog(@"main");
else
NSLog(@"non-main");
copy]
failureBlock:^(NSError * err)
NSLog(@"Erorr: %@", [err localizedDescription] );];
[library release];
if([NSThread isMainThread])
NSLog(@"main");
else
NSLog(@"non-main");
我的输出是
main
main
main
表示该块在主线程中被调用。这只是一个单独的事件。 要解决您的问题,您只需要在到达最后一步时从块内以某种方式返回您的值。你可以说这是最后一步,因为你的块将被调用为组对象的 nil。
编辑:例如使用这个块
^(ALAssetsGroup * group, BOOL * stop)
if(group == nil)
// we've enumerated all the groups
// do something to return a value somehow (maybe send a selector to a delegate)
【讨论】:
使用块结束解决方案虽然不是一个优雅的解决方案,但现在对我有用。【参考方案2】:答案就是这样使用 NSConditionLock 类...
typedef enum
completed = 0,
running = 1
threadState;
...
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:running];
然后分离你的线程,或者在我的情况下调用 [ALAssetsLibrary enumerateGroupsWithTypes:]。然后用这个阻塞父线程...
// Await completion of the worker threads
[lock lockWhenCondition:completed];
[lock unlockWithCondition:completed];
当 child/worker 线程中的所有工作都完成后,使用此线程解除对父线程的阻塞 ...
// Signal the waiting thread
[lock lockWhenCondition:running];
[lock unlockWithCondition:completed];
【讨论】:
你能告诉我更多关于这个解决方案的信息吗?【参考方案3】:只需使用这个:
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:[^(ALAssetsGroup * group, BOOL * stop)
if(group == nil)
// this is end of enumeration
.
.
.
【讨论】:
以上是关于使用 [ALAssetsLibrary enumerateGroupsWithTypes:] 时的 Cocoa 线程同步的主要内容,如果未能解决你的问题,请参考以下文章
保存图像元数据 PHPhotoLibrary 与 ALAssetsLibrary