2010-08-27 20 views
10

Recentemente, come alcune persone, ho scoperto che [ALAssetsLibrary enumerateGroupsWithTypes] piace eseguire i suoi blocchi su un altro thread. Peccato che Apple non l'abbia documentato :-)Sincronizzazione del thread di cacao quando si utilizza [ALAssetsLibrary enumerateGroupsWithTypes:]

Nella mia circostanza attuale devo attendere il completamento dell'enumerazione, prima che il thread principale restituisca risultati. Ho chiaramente bisogno di una sorta di sincronizzazione dei thread.

Ho letto su NSLock & NSConditionLock, ma nulla sembra ancora soddisfare il requisito di 'segnalare un thread bloccato che questo thread di lavoro ha completato'. Sembra un bisogno abbastanza semplice - qualcuno può indicarmi la giusta direzione?

vostri indizio & fischi, sono i benvenuti come sempre,

M.

risposta

2

La risposta è quella di utilizzare la classe NSConditionLock questa convenzione ...

typedef enum { 
    completed = 0, 
    running = 1 
} threadState; 

... 

NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:running]; 

Poi spin off tuo thread, o nel mio caso una chiamata a [ALAssetsLibrary enumerateGroupsWithTypes:]. Quindi bloccare il thread genitore con questo ...

// Await completion of the worker threads 
[lock lockWhenCondition:completed]; 
[lock unlockWithCondition:completed]; 

Quando tutto il lavoro è fatto nel bambino/lavoratore filo, sbloccare il genitore con questo ...

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

Potrebbe dirmi di più su questa soluzione? – MatterGoal

11

Il quadro doesn' t eseguire questi blocchi su un thread separato. Li esegue come eventi aggiuntivi nello stesso ciclo di esecuzione. Per provarlo, provate questo

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

mia uscita da questo stato

main 
main 
main 

che significa che il blocco è stato chiamato nel thread principale. È solo un evento separato. Per risolvere il tuo problema, devi solo restituire il tuo valore in qualche modo all'interno del blocco quando raggiungi l'ultimo passaggio. Puoi dire che è l'ultimo passo perché il tuo blocco verrà chiamato con zero per l'oggetto gruppo.

EDIT: per esempio utilizzare questo blocco

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

utilizzando la soluzione di fine blocco anche se non è elegante ma funziona per me per ora. – user523234

2

semplicemente utilizzare questo:

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