iOS 잠금 시리즈 - NSRecursiveLock 재귀적 잠금

2813 단어
원문에서 이 글은 NSRecursive Lock을 사용하는 것을 총괄적으로 배우기 위해 실제적으로 하나의 귀속 자물쇠를 정의했다. 이 자물쇠는 같은 라인에 여러 번 요청할 수 있고 사라진 자물쇠를 일으키지 않는다.이것은 주로 순환이나 귀속 작업에 쓰인다.먼저 예를 살펴보겠습니다.
NSLock *lock = [[NSLock alloc] init];
 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
    static void (^RecursiveMethod)(int);
 
    RecursiveMethod = ^(int value) {
 
        [lock lock];
        if (value > 0) {
 
            NSLog(@"value = %d", value);
            sleep(2);
            RecursiveMethod(value - 1);
        }
        [lock unlock];
    };
 
    RecursiveMethod(5);
});

이 코드는 전형적인 잠금 상태이다.우리의 스레드에서 Recursive Method는 귀속 호출됩니다.그래서 이 Block에 들어갈 때마다 자물쇠를 한 번 더 넣는다. 두 번째부터는 자물쇠가 사용되고 잠금이 풀리지 않기 때문에 자물쇠가 풀리기를 기다려야 한다. 그러면 자물쇠가 사라지고 라인이 막힌다.디버거에서 다음과 같은 정보가 출력됩니다.
value = 5
*** -[NSLock lock]: deadlock ( '(null)')   *** Break on _NSLockError() to debug.

이 경우 NSRecursiveLock을 사용할 수 있습니다.그것은 같은 라인에 여러 번 자물쇠를 잠그는 것을 허용할 수 있으며, 자물쇠가 사라지지 않는다.귀속 자물쇠는 lock의 횟수를 추적합니다.매번 성공한 lock은 unlock 동작을 균형 있게 호출해야 합니다.이 균형에 도달해야만 자물쇠가 마지막에 풀려 다른 라인에 사용될 수 있다.
그래서 위의 코드를 개조하고,
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];

그러면 프로그램이 다음과 같이 정상적으로 실행됩니다.
value = 5
value = 4
value = 3
value = 2
value = 1

NSRecursiveLock은 NSLocking 프로토콜을 구현하는 방법 외에 다음과 같은 두 가지 방법을 제공합니다.
//  
- (BOOL)lockBeforeDate:(NSDate *)limit
 
//  , , 
- (BOOL)tryLock


이 두 가지 방법은 다선정 상황에서 귀속 자물쇠를 요청한 다음에 귀환하는 브리 값에 따라 상응하는 처리를 시도하는 데 사용될 수 있다.코드는 다음과 같습니다.
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
    static void (^RecursiveMethod)(int);
 
    RecursiveMethod = ^(int value) {
 
        [lock lock];
        if (value > 0) {
 
            NSLog(@"value = %d", value);
            sleep(2);
            RecursiveMethod(value - 1);
        }
        [lock unlock];
    };
 
    RecursiveMethod(5);
});
 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
    sleep(2);
    BOOL flag = [lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    if (flag) {
        NSLog(@"lock before date");
 
        [lock unlock];
    } else {
        NSLog(@"fail to lock before date");
    }
});

앞의 코드에, 우리는 귀속 자물쇠를 얻기 위해 코드를 추가했다.우리는 두 번째 라인에서 귀속 자물쇠를 가져오려고 시도했다. 물론 이런 상황에서 실패할 것이다. 출력 결과는 다음과 같다.
value = 5
value = 4
fail to lock before date
value = 3
value = 2
value = 1

또한 NSRecursiveLock은 다음과 같은 name 속성을 선언합니다.
@property(copy) NSString *name

우리는 이 문자열을 사용하여 자물쇠를 표시할 수 있다.Cocoa에서도 이 name을 오류 설명 정보의 일부로 사용합니다.

좋은 웹페이지 즐겨찾기