Grand Central Dispatch
Grand Central Dispatch (GCD) 는 개발자들이 맥에 탑재된 멀티 코어를 최대로 활용할 수 있도록 도와주는 새로운 프레임웍입니다. 이것은 block 과 add 로 이루어진 Dispatch Queue 로 구성되어 있습니다. Dispatch Queue 는 전달인수나 리턴값이 없는 블럭을 큐로 저장하게 되며, 블럭을 큐에 입력하는 즉시 실행에 들어갑니다. 다음은 블럭을 큐에 어떻게 입력하는지 보여주는 예제입니다.
dispatch_async(queue, ^{
NSLog(@"Async");
});
비동기 실행이므로 이 구문은 곧바로 리턴됩니다. 이 블럭은 큐 내에서 실행되므로, 다른 쓰레드에서 실행될 수도 있습니다.
GCD 는 블럭을 백그라운드 쓰레드로 발송할 수 있도록 글로벌 큐를 지원합니다. 글로벌 큐에 입력된 블럭들도 서로 동시에 실행될 수 있습니다. 다음은 기본 우선권을 가지는 글로벌 큐를 얻어내는 방법입니다.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
이 두 줄을 합치면 매우 손쉽게 동시 실행을 구현할 수 있습니다.
GCD 는 또한 메인 쓰레드에 해당하는 큐를 제공합니다.
dispatch_queue_t queue = dispatch_get_main_queue() ;
메인 큐에 입력된 블럭은 메인 쓰레드에서 실행됩니다. 블럭은 또한 메인 큐 내에서 차례대로 실행되게 할 수 있으며, 이런 경우 동시실행은 지원되지 않고 큐에 입력된 순서 그대로 작업이 진행됩니다. 메인 큐를 이용하면 지금까지 작업을 메인 쓰레드로 옮겨주는 performSelectorOnMainThread: 메쏘드를 대체할 수 있습니다. 이 기능은 AppKit 을 메인 쓰레드에서만 억세스하는 경우 중요하며, 이 방법으로 위의 경우를 훨씬 쉽게 구현할 수 있습니다.
그렇다면 위의 기능을 이용해서 어떻게 하면 여러분의 프로그램에서 동시 실행 기능을 만들 수 있을까요? 여기에 시간이 조금 많이 걸리는 메쏘드가 있다고 생각해 봅시다. 만약 이 메쏘드를 버튼이 눌림과 동시에 메인 쓰레드에서 실행한다고 하면, 그에 따라 UI 쓰레드가 방해를 받을 가능성이 높습니다. 이렇게 되면 여러분 화면에는 회전하는 무지개 아이콘이 보이면서 프로그램은 먹통이 되어 버립니다. 다음과 같은 예제가 있습니다.
- (IBAction)buttonPressed:(id)sender
{
NSURL *url = [NSURL URLWithString:[_urlField stringValue]];
NSString *string = [self getStringFromUlr:url];
[_textField setStringValue:string];
}
이 코드에서, 만약 getStringFromUrl: 메쏘드 실행이 네트웍 작업으로 인하여 시간을 오래 잡아먹는다면, 그에 따라서 UI 쓰레드가 방해를 받습니다. 이런 경우를 피하기 위해서는 getStringFromUrl: 메쏘드의 실행을 백그라운드 쓰레드로 돌려야 합니다. 물론 텍스트 필드로 내어놓아야 할 결과물은 메인 쓰레드로 가져와야 합니다. GCD 와 블럭 기능을 이용하면 이 작업을 손쉽게 할 수 있습니다.
- (IBAction)buttonPressed:(id)sender
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
NSURL *url = [NSURL URLWithString:[_urlField stringValue]];
dispatch_async(concurrentQueue, ^{
NSString *string = [self getStringFromUrl:url];
dispatch_async(mainQueue, ^{
[_textField setStringValue:string];
});
});
}
먼저, 메인 쓰레드에서 URL 을 텍스트 필드로부터 받습니다. 그 다음 글로벌 동시 실행 큐를 이용하여 getStringFromUrl: 메쏘드를 백그라운드 쓰레드에서 실행합니다. 마지막으로, 메인 큐를 이용하여 UI 를 갱신합니다. 이 예제에서는 블럭들이 스택에 있는 변수를 억세스하는 기능을 확인할 수 있습니다. 예를 들어서 url 변수는 글로벌 큐 블럭에 있었고, string 변수는 메인 큐 블럭에 있었습니다.
동일한 코드를 GCD 와 블럭 없이 구현할 수도 있겠지만, 훨씬 더 복잡하게 짜야 합니다. 프로그램을 개별 메쏘드 단위로 쪼개어야 하고 필요한 쓰레드를 직접 만들어야겠지요. 그리고 객체를 메쏘드의 인수로 선언하여 전달해 주어야 합니다. 더 복잡한 경우는 인스턴스 변수를 만들어주어야 할 때도 있는데, 왜냐하면 performSelector 메쏘드는 객체 한두 개 밖에 전달할 수 없기 때문입니다. GCD 와 블럭은 이러한 복잡한 작업들을 없애줍니다.
GCD 에 대해서는 더 많은 내용이 있습니다. 필요한 큐를 직접 만들고, 블럭을 그룹으로 만들고, 실행 큐를 제어하는 등의 기능이 있습니다. 하지만 적어도 위의 예제에서는 GCD 를 이용하여 여러분이 얼마나 쉽게 동시 실행 기능을 가진 응용 프로그램을 만들 수 있는지를 볼 수 있을 것입니다.
Grand Central Dispatch (GCD) 는 개발자들이 맥에 탑재된 멀티 코어를 최대로 활용할 수 있도록 도와주는 새로운 프레임웍입니다. 이것은 block 과 add 로 이루어진 Dispatch Queue 로 구성되어 있습니다. Dispatch Queue 는 전달인수나 리턴값이 없는 블럭을 큐로 저장하게 되며, 블럭을 큐에 입력하는 즉시 실행에 들어갑니다. 다음은 블럭을 큐에 어떻게 입력하는지 보여주는 예제입니다.
dispatch_async(queue, ^{
NSLog(@"Async");
});
비동기 실행이므로 이 구문은 곧바로 리턴됩니다. 이 블럭은 큐 내에서 실행되므로, 다른 쓰레드에서 실행될 수도 있습니다.
GCD 는 블럭을 백그라운드 쓰레드로 발송할 수 있도록 글로벌 큐를 지원합니다. 글로벌 큐에 입력된 블럭들도 서로 동시에 실행될 수 있습니다. 다음은 기본 우선권을 가지는 글로벌 큐를 얻어내는 방법입니다.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
이 두 줄을 합치면 매우 손쉽게 동시 실행을 구현할 수 있습니다.
GCD 는 또한 메인 쓰레드에 해당하는 큐를 제공합니다.
dispatch_queue_t queue = dispatch_get_main_queue() ;
메인 큐에 입력된 블럭은 메인 쓰레드에서 실행됩니다. 블럭은 또한 메인 큐 내에서 차례대로 실행되게 할 수 있으며, 이런 경우 동시실행은 지원되지 않고 큐에 입력된 순서 그대로 작업이 진행됩니다. 메인 큐를 이용하면 지금까지 작업을 메인 쓰레드로 옮겨주는 performSelectorOnMainThread: 메쏘드를 대체할 수 있습니다. 이 기능은 AppKit 을 메인 쓰레드에서만 억세스하는 경우 중요하며, 이 방법으로 위의 경우를 훨씬 쉽게 구현할 수 있습니다.
그렇다면 위의 기능을 이용해서 어떻게 하면 여러분의 프로그램에서 동시 실행 기능을 만들 수 있을까요? 여기에 시간이 조금 많이 걸리는 메쏘드가 있다고 생각해 봅시다. 만약 이 메쏘드를 버튼이 눌림과 동시에 메인 쓰레드에서 실행한다고 하면, 그에 따라 UI 쓰레드가 방해를 받을 가능성이 높습니다. 이렇게 되면 여러분 화면에는 회전하는 무지개 아이콘이 보이면서 프로그램은 먹통이 되어 버립니다. 다음과 같은 예제가 있습니다.
- (IBAction)buttonPressed:(id)sender
{
NSURL *url = [NSURL URLWithString:[_urlField stringValue]];
NSString *string = [self getStringFromUlr:url];
[_textField setStringValue:string];
}
이 코드에서, 만약 getStringFromUrl: 메쏘드 실행이 네트웍 작업으로 인하여 시간을 오래 잡아먹는다면, 그에 따라서 UI 쓰레드가 방해를 받습니다. 이런 경우를 피하기 위해서는 getStringFromUrl: 메쏘드의 실행을 백그라운드 쓰레드로 돌려야 합니다. 물론 텍스트 필드로 내어놓아야 할 결과물은 메인 쓰레드로 가져와야 합니다. GCD 와 블럭 기능을 이용하면 이 작업을 손쉽게 할 수 있습니다.
- (IBAction)buttonPressed:(id)sender
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
NSURL *url = [NSURL URLWithString:[_urlField stringValue]];
dispatch_async(concurrentQueue, ^{
NSString *string = [self getStringFromUrl:url];
dispatch_async(mainQueue, ^{
[_textField setStringValue:string];
});
});
}
먼저, 메인 쓰레드에서 URL 을 텍스트 필드로부터 받습니다. 그 다음 글로벌 동시 실행 큐를 이용하여 getStringFromUrl: 메쏘드를 백그라운드 쓰레드에서 실행합니다. 마지막으로, 메인 큐를 이용하여 UI 를 갱신합니다. 이 예제에서는 블럭들이 스택에 있는 변수를 억세스하는 기능을 확인할 수 있습니다. 예를 들어서 url 변수는 글로벌 큐 블럭에 있었고, string 변수는 메인 큐 블럭에 있었습니다.
동일한 코드를 GCD 와 블럭 없이 구현할 수도 있겠지만, 훨씬 더 복잡하게 짜야 합니다. 프로그램을 개별 메쏘드 단위로 쪼개어야 하고 필요한 쓰레드를 직접 만들어야겠지요. 그리고 객체를 메쏘드의 인수로 선언하여 전달해 주어야 합니다. 더 복잡한 경우는 인스턴스 변수를 만들어주어야 할 때도 있는데, 왜냐하면 performSelector 메쏘드는 객체 한두 개 밖에 전달할 수 없기 때문입니다. GCD 와 블럭은 이러한 복잡한 작업들을 없애줍니다.
GCD 에 대해서는 더 많은 내용이 있습니다. 필요한 큐를 직접 만들고, 블럭을 그룹으로 만들고, 실행 큐를 제어하는 등의 기능이 있습니다. 하지만 적어도 위의 예제에서는 GCD 를 이용하여 여러분이 얼마나 쉽게 동시 실행 기능을 가진 응용 프로그램을 만들 수 있는지를 볼 수 있을 것입니다.
'프로그램 > iPhone' 카테고리의 다른 글
how to debug EXC_BAD_ACCESS on iPhone (0) | 2011.01.03 |
---|---|
아이콘과 로고-인트로-첫 화면 만들기 (0) | 2010.12.15 |
개발자 등록(등록비 $99)없이 디바이스에 어플리케이션 올리는 방법 (0) | 2010.11.27 |
아이폰 앱 76개 소스코드, 강좌, 개발 팁 링크모음 (0) | 2010.11.22 |
100 Free Courses & Tutorials for Aspiring iPhone App Developers (0) | 2010.11.16 |