我如何使用NSConditionLock? 或NSCondition

我试着做一个函数等待另一个,我想用NSCondionLock来完成这个。 我不是在寻求帮助,而是真的希望有人能给我一个体面的教程或例子来解释NSConditionLock,或者可能build议一个更好的方法。

编辑:作为@Bonshington评论,这个答案是指NSCondition (而不是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]; } 

someCheckIsTrue可以是任何东西,它可以是一个简单的BOOLvariables,甚至像[myArray count] == 0 && color == kColorRed ,没关系。 只有在一种方法中,您可以在有锁的情况下检查条件, 在另一种方法中,您可以在locking的情况下进行更改,使条件成为真实。 神奇的是waitsignal部分: wait实际上解锁了锁,并在一些其他线程调用signal之后重新获取它。

对于那些想要在这里举办一个示例testing课的人,我会发布我所做的工作,并了解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 */ 

NSConditionLock示例程序。

 #import <Foundation/Foundation.h> #define IDLE 0 #define START 1 #define TASK_1_FINISHED 2 #define TASK_2_FINISHED 3 #define CLEANUP_FINISHED 4 #define SHARED_DATA_LENGTH 1024 * 1024 * 1024 int main(int argc, const char * argv[]) { @autoreleasepool { NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:IDLE]; char *shared_data = calloc(SHARED_DATA_LENGTH, sizeof(char)); [NSThread detachNewThreadWithBlock:^{ [lock lockWhenCondition:START]; NSLog(@"[Thread-1]: Task 1 started..."); for (size_t i = 0; i < SHARED_DATA_LENGTH; i++) { shared_data[i] = 0x00; } [lock unlockWithCondition:TASK_1_FINISHED]; }]; [NSThread detachNewThreadWithBlock:^{ [lock lockWhenCondition:TASK_1_FINISHED]; NSLog(@"[Thread-2]: Task 2 started..."); for (size_t i = 0; i < SHARED_DATA_LENGTH; i++) { char c = shared_data[i]; shared_data[i] = ~c; } [lock unlockWithCondition:TASK_2_FINISHED]; }]; [NSThread detachNewThreadWithBlock:^{ [lock lockWhenCondition:TASK_2_FINISHED]; NSLog(@"[Thread-3]: Cleaning up..."); free(shared_data); [lock unlockWithCondition:CLEANUP_FINISHED]; }]; NSLog(@"[Thread-main]: Threads set up. Waiting for 2 task to finish"); [lock unlockWithCondition:START]; [lock lockWhenCondition:CLEANUP_FINISHED]; NSLog(@"[Thread-main]: Completed"); } return 0; }