Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save linearhw/25e42be8d7fa74fb9ab7e8f80da73a29 to your computer and use it in GitHub Desktop.
Save linearhw/25e42be8d7fa74fb9ab7e8f80da73a29 to your computer and use it in GitHub Desktop.
Effective Objective-C 41

다시 짚고 가는 sync 와 async 의 차이

  • sync 는 current thread 를 작업이 다 끝날 때까지 block 한다
  • async 는 current thread 를 건드리지 않는다. 새로운 thread를 따로 만들거나 해서 실행시킨다.
    그러니 어느 쪽이 먼저 실행될 지는 알 수 없다.

앞에선 async 를 잘 처리하는 방법에 대해 배웠다. sync 는 어떻게 하면 좋은가?

  • GCD 이전엔 두 가지 방법이 있었다.
    1. 내장된 동기화 블록 사용하기 -> 남용하면 위험하다. 모든 블록이 서로를 동기화할 것이다.
    2. NSLock 객체를 직접 사용하기
  • 하지만 둘 다 문제가 있다. 데드락에 대한 처리가 힘들기 때문.
  • 대안은 GCD 를 사용하는 것이다.

예를 들어 property 의 경우 읽기, 쓰기 등의 operation 을 하나의 serial queue 에서 하도록 만들 수 있다.

_syncQueue = dispatch_queue_create("com.effectiveobjectivec.syncQueue", NULL);

- (NSString*)someString {
    __block NSString *localSomeString;
    dispatch_sync(_syncQueue, ^{
        localSomeString = _someString;
    });
    return localSomeString;
}

- (void)setSomeString:(NSString*)someString {
    dispatch_sync(_syncQueue, ^{
        _someString = someString;
    });
}

더 빠르게 하는 방법

  • 사실 setter 는 굳이 sync 여야 할 필요가 없다. 뭔가 return 하는 게 아니니까. 그러니 async 로 바꾸자.
    (getter 를 async 로 바꾸면? localSomeString가 nil인 채로 return 될 것이다.)

  • 비동기의 경우 실행할 블록을 복사해야 하기 때문에
    (블록을 복사하는 데 걸리는 시간 > 블록을 실행할 때 걸리는 시간)일 때는 sync 가 더 빠르다
    하지만 실행 시간이 더 긴 경우에는 async 가 더 좋은 방법이다.

  • serial queue 로 되어있는 걸 concurrent queue 로 바꾸고 대신 barrier 를 도입하자.
    barrier 는 queue 의 모든 다른 블록과는 배타적으로 실행된다.
    (현재 실행 중인 모든 블록이 끝나길 기다림 -> barrier 블록 실행 -> barrier 블록 끝나면 다시 작업 재개)
    물론 concurrent queue 에서만 의미가 있는 기능이다.

_syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

- (NSString*)someString {
    __block NSString *localSomeString;
    dispatch_sync(_syncQueue, ^{
        localSomeString = _someString;
    });
    return localSomeString;
}

- (void)setSomeString:(NSString*)someString {
    dispatch_barrier_async(_syncQueue, ^{
        _someString = someString;
    });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment