2012년 4월 19일 목요일

[iOS] 특정 코드를 비동기로 실행시키기

특정 API를 호출했는데 이 API가 작업시간이 오래 걸린다면 UI가 그 동안 멈추는 현상이 발생한다. 예를 들자면 대용량 파일을 읽거나 쓸 때 그 동안은 UI가 동작하지 않는 경우가 있다. 이 문제를 회피하려면 오래 걸리는 작업을 비동기(Asynchronous)로 처리하도록 할 수 있다.

이런 경우를 위해서 애플이 만든 GCD(Grand Central Dispatch)라 불리우는 기술(개념?)을 이용 할 수 있다. 쓰레드로 분리된 큐에 작업 내용을 넣어서 이를 차례대로 실행시키는 방식으로, 백그라운드 프로세싱과 병렬 처리를 한방에 해결 할 수 있도록 해 주는 고마운 기능이다.

우선 가정부터. heavyOperatingMethod라는 메서드가 작업 시간이 오래 걸리지만 UI는 이 메서드가 리턴하는 값을 이용해야 한다. 하지만 heavyOperatingMethod의 응답을 기다리기에는 UI가 그냥 멈춰버리기 때문에 사용자에게서 불만이 생길 것 같다. 이 경우 heavyOperatingMethod를 비동기로 처리해보자. 아래 코드는 그 예제 코드이다.
// 여기서부터 비동기 코드 시작.
// dispatch_async 함수는 내부블럭의 코드 실행에 영향을 받지 않고 바로 실행이 끝난다.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
    // 작업이 오래 걸리는 API를 백그라운드 스레드에서 실행한다.
    BOOL res = [self heavyOperatingMethod];

    dispatch_async(dispatch_get_main_queue(), ^{
        // 이 블럭은 메인스레드(UI)에서 실행된다.
        if (res) {
            [self operationSucceed];
        } else {
            [self operationFailed];
        }
    });
});
위 코드 예제는 앞서 이야기한 GCD(Grand Central Dispatch)라 불리우는 기술을 이용한 것이다.

앱이 동작 할 때는 앱의 메인스레드가 반드시 존재한다. 이는 UI 등 앱이 실행되는 스레드로써, 이 스레드에서의 특정 작업이 지체될 경우 앱이 얼어버리는(Freezing) 현상이 발생한다. 그렇다면 이 지체되는 작업을 병렬로 처리해야 된다.

그리고 iOS나 OS X에서 앱이 동작 할 때 역시 기본적으로 글로발 큐(Global Queue)도 생성된다. 그것도 여러 우선순위(Priority)로 동작시킬 수 있도록 구성되어 있다. 이 글로발 큐는 UI와는 별도로 동작하는 스레드를 생성시켜서 동작한다.

결국 위 코드는 백그라운드 스레드에 힘든 작업을 떠맞기고 UI스레드는 탱자탱자 놀게 만드는 코드이다.

[관련글] [iOS] 블럭 문법 (Blocks Programming)
[관련글] Swift - 병렬 프로그래밍(Concurrency Programming) 가이드

댓글 1개 :

익명 :

좋은 정보 감사합니다.
-김형석-