NSMethodSignature & NSInvocation
Cocoa 프로그래밍에서는 위 두개의 클래스를 소개한다.
이는 SDK 2.0이상 사용이 가능하며 iOS 개발에도 유용하게 사용할 수 있다.
메시지 포워딩 또는 n개 이상의 Argument를 전달할 때 사용 할 수 있으며,
실제로 두 클래스는 NSObject클래스에 정의 되어 오버라이딩하여 사용한다.
아래는 예제 코드이다.
[sourcecode language="objc"]
//
// main.c
// MessageForwarding
//
// Created by hojun baek on 11. 4. 6..
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import
#import
#import
#import
#import
#import
@interface EZTest : NSObject{
NSString *str;
}
@end
@implementation EZTest
- (id)initWithString:(NSString *)theStr {
self = [super init];
if (self) {
str = [theStr retain];
}
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
if ([super respondsToSelector:aSelector]) {
return [super methodSignatureForSelector:aSelector];
} else {
return [str methodSignatureForSelector:aSelector];
}
}
- (BOOL)respondsToSelector:(SEL)aSelector{
if([super respondsToSelector:aSelector])
return YES;
if([self methodForSelector:aSelector] != (IMP)NULL)
return YES;
if ([str methodForSelector:aSelector]) {
return YES;
}
return NO;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation{
SEL sel = [anInvocation selector];
if ([super respondsToSelector:sel]) {
[super forwardInvocation:anInvocation];
} else {
[anInvocation invokeWithTarget:str];
}
}
// send message with argument.
- (void)print {
SEL selector = @selector(sendWithMsg1:msg2:msg3:);
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:selector];
NSString *msg1 = @"welcome ";
NSString *msg2 = @"to ";
NSString *msg3 = @"easy cocoa";
[invocation setArgument:&msg1 atIndex:2];
[invocation setArgument:&msg2 atIndex:3];
[invocation setArgument:&msg3 atIndex:4];
[invocation retainArguments];
[invocation invoke];
}
- (void)sendWithMsg1:(NSString *)msg1 msg2:(NSString *)msg2 msg3:(NSString *)msg3 {
NSLog(@"%@%@%@", msg1, msg2, msg3);
}
@end
int main (int argc, const char * argv[]) {
id test;
id pool = [[NSAutoreleasePool alloc] init];
test = [[EZTest alloc] initWithString:@"hello "];
NSLog(@"%@",[test stringByAppendingFormat:@"world"]);
[test print];
[test release];
[pool release];
return 0;
}
[/sourcecode]