我如何使用NSConditionLock?或NSCondition

gur*_*ooj 31 iphone locking conditional-statements ios

我试图使一个函数等待另一个函数,我想使用NSCondionLock来实现这一目标.我不是在寻求帮助,但我真的希望有人能给我一个体面的教程或示例来解释NSConditionLock,或者可能建议一个更好的方法.

Dar*_*ust 49

编辑:正如@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];
}
Run Code Online (Sandbox Code Playgroud)

someCheckIsTrue可以是任何东西,它可能是一个简单的布尔变量,甚至有点像[myArray count] == 0 && color == kColorRed,也没关系.只有在一种方法中,您在锁定时检查条件并且在另一种方法中进行更改才能使条件在锁定时变为真.神奇的是在waitsignal部分:wait其实解锁锁定有的叫其他线程后重新获取它signal.

  • NSConditionLock没有等待,信号.它的NSCondition (14认同)
  • 你应该将它声明为你的类中的实例变量,`NSConditionLock*lock;`.然后使用`lock = [[NSConditionLock alloc] init]来在`init`中初始化它;`就是这样.另外,在`dealloc`中,你只需释放它:`[lock release];`.或者如果方法在不同的类中,那么您需要在两个方法都可以访问的位置定义锁. (2认同)

vil*_*ovi 32

对于那些想要在这里进行样本测试课程的人,我发布了我要做的事情,并了解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
*/
Run Code Online (Sandbox Code Playgroud)


Iva*_*nin 5

@vilanovi 的Swift 5版本来自 Playground 的回答:

let myCondition = NSCondition()

var someCheckIsTrue = false

func method1() {
    print("STARTING METHOD 1")

    print("WILL LOCK METHOD 1")
    myCondition.lock()
    print("DID LOCK METHOD 1")

    while (!someCheckIsTrue) {
        print("WILL WAIT METHOD 1")
        myCondition.wait()
        print("DID WAIT METHOD 1")
    }

    print("WILL UNLOCK METHOD 1")
    myCondition.unlock()
    print("DID UNLOCK METHOD 1")

    print("ENDING METHOD 1")
}

func method2() {
    print("STARTING METHOD 2")

    print("WILL LOCK METHOD 2")
    myCondition.lock()
    print("DID LOCK METHOD 2")

    someCheckIsTrue = true

    print("WILL SIGNAL METHOD 2")
    myCondition.signal()
    print("DID SIGNAL METHOD 2")

    print("WILL UNLOCK METHOD 2")
    myCondition.unlock()
    print("DID UNLOCK METHOD 2")

    print("ENDING METHOD 2")
}

DispatchQueue.global().async {
    method1()
}

DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 0.5) {
    method2()
}
Run Code Online (Sandbox Code Playgroud)