¿Cómo uso NSConditionLock? O NScondición

Estoy tratando de hacer que una function espere a otra, y me gustaría usar NSCondionLock para lograr esto. No estoy pidiendo ayuda, pero realmente espero que alguien me muestre un tutorial o ejemplo decente para explicar NSConditionLock, o posiblemente sugiera un método mejor.

EDIT: como @Bonshington comentó, esta respuesta se refiere a NSCondition (a diferencia de NSConditionLock ):

 - (void) method1 { [myCondition lock]; while (!someCheckIsTrue) [myCondition wait]; // Do something. [myCondition unlock]; } - (void) method2 { [myCondition lock]; // Do something. someCheckIsTrue = YES; [myCondition signal]; [myCondition unlock]; } 

El someCheckIsTrue puede ser cualquier cosa, podría ser una simple variable BOOL o incluso algo así como [myArray count] == 0 && color == kColorRed , no importa. Solo importa que en un método verifiques una condición mientras tienes el locking y en otro método realizas cambios que pueden hacer que la condición se vuelva verdadera también mientras tienes el locking . La magia es la parte de wait y signal : la wait realmente desbloquea el locking y lo vuelve a adquirir después de otro hilo llamado signal .

Para aquellos que quieren una class de testing de ejemplo, aquí publico lo que hice para jugar y entender cómo funciona NSCondition.

 // --- MyTestClass.h File --- // @interface MyTestClass - (void)startTest; @end // --- MyTestClass.m File --- // @implementation MyTestClass { NSCondition *_myCondition; BOOL _someCheckIsTrue; } - (id)init { self = [super init]; if (self) { _someCheckIsTrue = NO; _myCondition = [[NSCondition alloc] init]; } return self; } #pragma mark Public Methods - (void)startTest { [self performSelectorInBackground:@selector(_method1) withObject:nil]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(5); [self performSelectorInBackground:@selector(_method2) withObject:nil]; }); } #pragma mark Private Methods - (void)_method1 { NSLog(@"STARTING METHOD 1"); NSLog(@"WILL LOCK METHOD 1"); [_myCondition lock]; NSLog(@"DID LOCK METHOD 1"); while (!_someCheckIsTrue) { NSLog(@"WILL WAIT METHOD 1"); [_myCondition wait]; NSLog(@"DID WAIT METHOD 1"); } NSLog(@"WILL UNLOCK METHOD 1"); [_myCondition unlock]; NSLog(@"DID UNLOCK METHOD 1"); NSLog(@"ENDING METHOD 1"); } - (void)_method2 { NSLog(@"STARTING METHOD 2"); NSLog(@"WILL LOCK METHOD 2"); [_myCondition lock]; NSLog(@"DID LOCK METHOD 2"); _someCheckIsTrue = YES; NSLog(@"WILL SIGNAL METHOD 2"); [_myCondition signal]; NSLog(@"DID SIGNAL METHOD 2"); NSLog(@"WILL UNLOCK METHOD 2"); [_myCondition unlock]; NSLog(@"DID UNLOCK METHOD 2"); } @end // --- Output --- // /* 2012-11-14 11:01:21.416 MyApp[8375:3907] STARTING METHOD 1 2012-11-14 11:01:21.418 MyApp[8375:3907] WILL LOCK METHOD 1 2012-11-14 11:01:21.419 MyApp[8375:3907] DID LOCK METHOD 1 2012-11-14 11:01:21.421 MyApp[8375:3907] WILL WAIT METHOD 1 2012-11-14 11:01:26.418 MyApp[8375:4807] STARTING METHOD 2 2012-11-14 11:01:26.419 MyApp[8375:4807] WILL LOCK METHOD 2 2012-11-14 11:01:26.419 MyApp[8375:4807] DID LOCK METHOD 2 2012-11-14 11:01:26.420 MyApp[8375:4807] WILL SIGNAL METHOD 2 2012-11-14 11:01:26.420 MyApp[8375:4807] DID SIGNAL METHOD 2 2012-11-14 11:01:26.421 MyApp[8375:4807] WILL UNLOCK METHOD 2 2012-11-14 11:01:26.421 MyApp[8375:3907] DID WAIT METHOD 1 2012-11-14 11:01:26.421 MyApp[8375:4807] DID UNLOCK METHOD 2 2012-11-14 11:01:26.422 MyApp[8375:3907] WILL UNLOCK METHOD 1 2012-11-14 11:01:26.423 MyApp[8375:3907] DID UNLOCK METHOD 1 2012-11-14 11:01:26.423 MyApp[8375:3907] ENDING METHOD 1 */