검색결과 리스트
글
다중인자를 갖는 PerformSelector 메시지
Objective-C
2011. 3. 23. 15:31
이번 포스팅에서는 다중 파라미터를 갖는 Selector를 인자로 받아 별도의 쓰레드에서 처리를 해주는 비동기 메서드
구현에 대해서 알아볼 것이다.
아이폰 앱 프로젝트 진행 중 Delegate 패턴을 구현하면서 PerformSelector 류의 메서드를 사용 할 필요가 생겼다.
Cocoa Touch 프레임웍에서는 최대 2개까지의 인자를 받는 메서드(performSelector:withObject:withObject:) 만을 제공하고,
더 많은 파라미터를 전달해야 할 경우, 클래스 또는 Dictionary를 사용하여 전달해야 했다. 매번마다 파라미터를 담기위해 Dictionary를 생성하고, 데이터를 꺼내쓰는 것은 상당히 번거로운 작업이었다.
외국 블로그에서 우연히 이 문제를 깔끔하게 해결해주는 코드를 발견했다. C언어의 가변인자 리스트와 Objective-C 의
NSInvocation 메커니즘을 사용하는 방법이었다. 이 포스팅에서는 가변인자 리스트와 NSInvocation 메커니즘에 대해서는
설명하지 않겠다. 추후 Objective-C 런타임 메커니즘을 알아보면서 NSInvocation에 대해서 자세히 알아볼 것이다.
Cocoa Touch 프레임웍에서는 최대 2개까지의 인자를 받는 메서드(performSelector:withObject:withObject:) 만을 제공하고,
더 많은 파라미터를 전달해야 할 경우, 클래스 또는 Dictionary를 사용하여 전달해야 했다. 매번마다 파라미터를 담기위해 Dictionary를 생성하고, 데이터를 꺼내쓰는 것은 상당히 번거로운 작업이었다.
외국 블로그에서 우연히 이 문제를 깔끔하게 해결해주는 코드를 발견했다. C언어의 가변인자 리스트와 Objective-C 의
NSInvocation 메커니즘을 사용하는 방법이었다. 이 포스팅에서는 가변인자 리스트와 NSInvocation 메커니즘에 대해서는
설명하지 않겠다. 추후 Objective-C 런타임 메커니즘을 알아보면서 NSInvocation에 대해서 자세히 알아볼 것이다.
다음은 가변인자 리스트와 NSInvocation을 사용하여 다중 파라미터를 갖는 Selector를 호출하는 예제코드이다.
- (void)performSelector:(SEL)aSelector withContext:(void*)context,... {
if (context) {
NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation retainArguments];
NSUInteger argumentCount = [signature numberOfArguments] - 2;
[invocation setTarget:self]; // index 0
[invocation setSelector:aSelector]; // index 1
va_list arguments;
va_start(arguments, context);
// 인자의 개수는 +2가 된 상태
NSUInteger i, count = argumentCount;
void *currentValue = context;
for (i = 0; i < count; i++) {
[invocation setArgument:¤tValue atIndex:(i + 2)];
currentValue = va_arg(arguments, void*); // 다음 인자 읽기
}
va_end(arguments);
NSThread *customWorkerThread = [NSThread currentThread];
[invocation performSelector:@selector(invoke) onThread:customWorkerThread withObject:nil waitUntilDone:NO];
} else {
[self performSelectorInBackground:aSelector withObject:nil];
}
}
위 메서드를 사용하여 아래와 같이 세 개의 인자를 갖는 printArgument:andOther:andAnother: 메시지를 호출하면...
// 호출할 메서드
- (void)printArgument:(NSString*)arg1 andOther:(NSString*)arg2 andAnother:(NSString*)arg3 {
NSLog(@"%@", [NSThread currentThread]);
NSLog(@"arg1: %@", arg1);
NSLog(@"arg2: %@", arg2);
NSLog(@"arg3: %@", arg3);
}
// 요렇게 호출할 수 있다. 깔끔하지 않는가? [self performSelector:@selector(printArgument:andOther:andAnother:) withContext:@"t1", @"t2", @"t3", nil];
위 메소드를 카테고리로 정의해놓으면 아주 유용하게 사용할 수 있을 것이다.
[소스 출처]
'Objective-C' 카테고리의 다른 글
| Objective-C 문자열 조작 메서드 (0) | 2011.04.29 |
|---|---|
| 다중인자를 갖는 PerformSelector 메시지 (0) | 2011.03.23 |
| Protocol 과 Category (0) | 2011.03.22 |
| Objective-C 훑어보기 (2) | 2011.03.20 |
| [Cocoa] Cocoa Design Pattern (0) | 2011.03.20 |
| HMAC-SHA1 구현 (0) | 2011.03.03 |