Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
605 views
in Technique[技术] by (71.8m points)

iphone - Cocoa thread synchronisation when using [ALAssetsLibrary enumerateGroupsWithTypes:]

I have recently, like a few people, discovered that [ALAssetsLibrary enumerateGroupsWithTypes] likes to run its blocks on another thread. What a shame that Apple didn't document that :-)

In my current circumstance I need to wait for the enumeration to complete, before the main thread returns any results. I clearly need some sort of thread synchronisation.

I've read about NSLock & NSConditionLock, but nothing yet seems to fit the requirement of 'signal a blocked thread that this worker thread has completed'. It seems like a simple enough need - can anyone point me in the right direction?

Your clue & boos, are most welcome as always,

M.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The framework doesn't run these blocks on a separate thread. It just runs them as additional events in the same run-loop. To prove it, try this

    [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");
    }

My output from this was

main
main
main

Meaning that the block was being called in the main thread. It's just a separate event. To solve your problem, you just need to return your value somehow from within the block when you reach the last step. You can tell it's the last step because your block will be called with nil for the group object.

EDIT: for instance use this block

^(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)
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...