2010-08-27 59 views
10

时可可线程同步最近,像一些人一样,发现[ALAssetsLibrary enumerateGroupsWithTypes]喜欢在另一个线程上运行其块。真可惜,苹果并没有文件证明:-)使用[ALAssetsLibrary enumerateGroupsWithTypes:]

在我目前的情况下,我需要等待枚举完成,主线程返回任何结果之前。我显然需要某种线程同步。

我已阅读关于NSLock & NSConditionLock,但似乎没有任何东西符合'发出此工作线程已完成的阻塞线程'的要求。这似乎是一个足够简单的需求 - 任何人都可以指出我的方向正确吗?

您的线索&嘘声,是最欢迎一如既往,

M.

回答

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]; 

当所有工作在子/工人线程完成,解锁这个父...

// Signal the waiting thread 
[lock lockWhenCondition:running]; 
[lock unlockWithCondition:completed]; 
+1

你能告诉我更多关于该解决方案? – MatterGoal 2011-04-28 12:07:09

11

框架没有按”在一个单独的线程上运行这些块。它只是在同一个运行循环中将它们作为附加事件运行。为了证明这一点,试试这个

[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) 
    } 
} 
+0

使用块的解决方案虽然不是一个优雅的,但现在为我工作。 – user523234 2011-08-09 13:54:05

2

只需使用这样的:

[library enumerateGroupsWithTypes:ALAssetsGroupAll 
          usingBlock:[^(ALAssetsGroup * group, BOOL * stop) 
{ 
    if(group == nil) 
    { 
     // this is end of enumeration 
    } 
} 
. 
. 
. 
相关问题