代码之家  ›  专栏  ›  技术社区  ›  Martin Cowie

使用[ALAssetsLibrary enumerateGroupsWithTypes:]时的可可线程同步

  •  10
  • Martin Cowie  · 技术社区  · 15 年前

    我最近和一些人一样,发现 [ALAssetsLibrary枚举组类型] 喜欢在另一个线程上运行它的块。苹果没有记录这一点真是太可惜了:-)

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

    我已经读过NSLock和NSConditionLock的相关内容,但似乎还没有什么内容符合“向阻塞的线程发送信号,表明此工作线程已完成”的要求。这似乎是一个足够简单的需要-有人能给我指出正确的方向吗?

    你的提示和嘘声一如既往地受到欢迎,

    M。

    3 回复  |  直到 15 年前
        1
  •  11
  •   George    14 年前

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

        [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
    

    编辑: 例如,使用此块

    ^(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
  •  2
  •   Martin Cowie    15 年前

    答案是这样使用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];
    
        3
  •  2
  •   AVEbrahimi    11 年前

    简单地使用这个:

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