2010-08-27 57 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 
    } 
} 
. 
. 
.