2009-07-07 16 views

risposta

8

Non ho molta familiarità con ManualResetEvent, ma based on the documentation, sembra che the NSCondition class potrebbe essere quello che stai cercando.

NSCondition non è affatto un equivalente esatto, ma fornisce funzionalità di segnalazione simili. Si potrebbe anche voler leggere su NSLock.

+1

Leggendo il documento sembra che faccia esattamente ciò di cui avevo bisogno. Grazie! – Lounges

+0

Sembra che NSCondition sia più simile a AutoResetEvent e non ManualResetEvent. – Brett

+0

Dai un'occhiata a questo utile esempio: http: //stackoverflow.com/questions/6158397/equivalent-of-gcd-serial-dispatch-queue-in-ios-3-x/6258379#6258379 – Brett

0

Ah, quelle sono le variabili di condizione di uomo povero.

È possibile utilizzare la classe NSCondition, ma penso che sia meglio
andare direttamente alla fonte. Inizia con pthread_cond_init.

Ti piacerà moltissimo.

+0

NSCondition è un wrapper di livello superiore intorno a pthreads. Se l'interfaccia NSCondition/NSLock fa il lavoro, non è necessario andare a basso livello. – Naaff

+0

Beh, immagino che potresti farlo nel modo più semplice. –

1

Ti darò il codice di esempio che avrei voluto trovare ieri (ma non è stato possibile trovare da nessuna parte). Se si desidera creare una classe produttore/consumatore in cui il consumatore è asincrono, è ciò che è necessario fare:

È necessario dichiarare e allocare NSConditionLock.

NSArray * data = [self getSomeData]; 

if ([data count] == 0) { 
    NSLog(@"sendThread: Waiting..."); 
    [_conditionLock lockWhenCondition:1]; 
    [_conditionLock unlockWithCondition:0]; 
    NSLog(@"sendThread: Back to life..."); 
} 
else { 
    // Processing 
} 

E nel codice principale, quando si aggiungono i dati e si desidera sbloccare l'altro thread, basta aggiungere:

[_conditionLock lock]; 
[_conditionLock unlockWithCondition:1]; 

Nota: Non descrivo qui come i dati siano scambiato tra il produttore e il consumatore. Nel mio programma stava passando attraverso un database SQLite/CoreData, quindi la sincronizzazione dei thread è fatta a un livello più alto. Ma se si usa NSMutableDictionary, è necessario aggiungere alcuni NSLock.

0

Ecco una classe wrapper che ho creato che emula ManualResetEvent utilizzando NSCondition.

@interface WaitEvent : NSObject { 
    NSCondition *_condition; 
    bool _signaled; 
} 

- (id)initSignaled:(BOOL)signaled; 
- (void)waitForSignal; 
- (void)signal; 

@end 

@implementation WaitEvent 

- (id)initSignaled:(BOOL)signaled 
{ 
    if (self = ([super init])) { 
     _condition = [[NSCondition alloc] init]; 
     _signaled = signaled; 
    } 

    return self; 
} 

- (void)waitForSignal 
{ 
    [_condition lock]; 
    while (!_signaled) { 
     [_condition wait]; 
    } 

    [_condition unlock]; 
} 

- (void)signal 
{ 
    [_condition lock]; 
    _signaled = YES; 
    [_condition signal]; 
    [_condition unlock]; 
} 

@end 

ho fatto solo alcuni test di base, ma penso che dovrebbe ottenere il lavoro fatto con molto meno cerimonia.