[Effective Objective-C] #43 GCD 가 필요한 때와 작업 큐가 필요한 때를 구분해서 알아두라
출처 : Effective Objective-C
-
GCD 는 환상적인 기술이지만 표준 시스템 라이브러리의 일부분인 도구들을 사용하는 것이 더 좋을 때가 있다.
언제 그런 도구를 사용해야 하는지 반드시 알고 있어야 한다.
도구를 잘못 사용하면 유지 보수하기 어려운 코드가 되기 쉽기 때문이다.
-
백그라운드로 일을 수행하는 최선의 방법이 항상 GCD 를 사용하는 것이 아니다.
관련 있는 기술이지만 별개인 NSOperationQueue 는 선택적으로 병렬로 동작하는 큐 관련 작업을 할 수 있게 한다.(NSOperation 의 하위 클래스)
-
알아야 할 첫 번째 차이점은 GCD 는 순정 C API 라는 것이다.
반면에 작업 큐는 오브젝티브-C 객체다.
GCD에서 큐에 있는 작업은 블록이다.
이는 매우 가벼운 데이터 구조체다.
반면에 작업은 오브젝티브-C 객체다.
그렇기 때문에 좀 더 무겁다.
그러나 GCD가 항상 사용되어야 한다는 것은 아니다.
때때로 객체를 사용하는 부하가 작을 수도 있고, 완전한 객체를 사용하는 이점이 단점을 상회할 때도 있다.
-
NSBlockOperation 또는 NSOperationQueue의 addOperationWithBlock: 메서드를 사용하는 것을 보면 작업 큐의 문법은 평범은 GCD 와 매우 비슷하게 보일 수 있다.
여기에 NSOperation 과 NSOperationQueue 를 사용할 때의 이점 몇 가지가 있다.
작업 취소
작업 큐를 사용하면 취소는 간단히 할 수 있다.
실행할 때 NSOperation 의 cancel 메서드는 작업 안에 내부 표식을 설정한다.
이미 시작된 작업은 취소하지 못할지라도 이는 작업이 실행되지 않는다는 것을 의미한다.
반면에 GCD 큐는 이미 스케줄된 블록을 취소할 수 있는 방법이 없다.
이 아키텍처는 실행하고 잃어버리기(fire and forget) 다.
앱 수준의 구현으로 취소를 구현할 수도 있지만 작업 형태로 이미 작성된 코드에 많은 코드를 작성해야 한다.
의존 작업
작업은 원하는 만큼 많은 다른 작업들에 의존할 수 있다.
이는 어떤 작업이 다른 작업이 성공적으로 수행된 후에 실행할 수 있게 하는 작업의 계층(hierarchy of operations)을 만들 수 있게 한다.
작업 프로퍼티의 키-값 관찰
작업은 KVO 에 적합한 많은 프로퍼티를 가지고 있다.
이러한 프로퍼티는 작업이 취소되었는지 확인하는 isCancelled 와 작업이 끝났는지 확인하는 isFinished 같은 것이 있다.
KVO 를 사용하면 언제 특정 작업의 상태가 변경되었는지 알 수 있고 동작 중인 태스크에 대해 GCD 보다 세세한 제어를 할 수 있다.
작업 우선순위
각 작업은 우선순위가 있다.
이는 큐의 작업들 간의 순위를 매긴다.
우선순위가 높은 작업은 우선순위가 낮은 것들보다 먼저 실행된다.
스케줄링 알고리즘은 투명하지만 매우 신중하게 다루어질 것이다.
GCD 는 같은 일을 하는 직접적인 방법이 없다.
GCD 는 큐 우선순위를 가지지만 개별 블록이 아닌 전체 큐에 대해 우선순위를 설정한다.
작업의 재사용
NSBlockOperation 같은 NSOperation 의 구성 하위 클래스(concrete subclass) 중 하나를 사용하지 않으면 스스로 자신의 하위 클래스를 생성해야 한다.
평범한 오브젝티브-C 객체인 이 클래스는 여러분이 원하는 모든 정보를 저장할 수 있다.
객체가 동작 중일 때 이 정보를 모두 사용할 수 있다.
그리고 그 클래스에 정의된 모든 메서드도 마찬가지로 사용 가능하다.
이로 인해 디스패치 큐에 들어 있는 간단한 블록에 비해 작업이 매우 강력해진다.
이러한 작업 클래스는 코드 내에서 재사용할 수 있다.
-
작업 큐는 주로 태스크를 실행할 때 여러분이 하려고 하는 많은 일들에 대한 즉각적인 해결책을 제공한다.
복잡한 스케줄러, 취소 기능, 우선순위를 직접 작성하는 대신에 작업 큐를 사용하면 공짜로 해당 기능을 얻을 수 있다.
-
가능한 한 가장 고수준의 API 를 사용해야 한다고 가끔 들었을 것이다.
그리고 오직 정말로 필요할 때만 저수준으로 내려가야 한다고 말이다.
나는 이 생각을 지지한다.
그러나 조심해야 한다.
단지 고수준 오브젝티브-C 로 할 수 있다고 이를 더 좋게 만들 필요가 없다는 것은 아니기 때문이다.
성능 테스트는 어떤 것이 더 좋은지 확인하는 최선의 방법이다.
기억할 점
-
디스패치 큐는 멀티스레드와 태스크 관리의 유일한 해결책은 아니다.
-
작업 큐는 GCD 가 하는 대부분의 일을 할 수 있는 고수준 오브젝티브-C API 를 제공한다.
또한 이러한 큐들은 GCD 로 한다면 추가적인 코드를 작성해야 하는 좀 더 복잡한 일들을 쉽게 할 수 있다.
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[Effective Objective-C] #45 스레드 안전한 단일 시간 코드 실행은 dispatch_once 를 이용하라 (1) | 2017.10.10 |
---|---|
[Effective Objective-C] #44 플랫폼 확장의 이점을 얻으려면 디스패치 그룹을 사용하라 (0) | 2017.10.09 |
[Effective Objective-C] #42 performSelector 메서드군보다는 GCD 를 사용하라 (0) | 2017.10.07 |
[Effective Objective-C] #41 동기화에는 락보다는 디스패치 큐를 사용하라 (0) | 2017.10.06 |
[Effective Objective-C] 목차와 요약을 통해 한 눈에 알아보는 Effective Objective-C #33 ~ #40 (0) | 2017.10.05 |
댓글