2011-10-13 4 views

답변

2

블록을 사용하면 아마도 va_args 마술을해야합니다. 가변 인수를 사용하여 선택기를 호출 할 수 있지만 아마 일부 도우미가 약간 덜 고통스럽게 만들고 싶을 수도 있습니다.

NSObject의 + performSelectorWithArgsArray.h

@interface NSObject (performSelectorWithArgsArray) 
- (id)performSelector:(SEL)sel withArgsArray:(NSArray *)args; 
@end 

NSObject의 + performSelectorWithArgsArray.m

@implementation NSObject (performSelectorWithArgsArray) 
- (id)performSelector:(SEL)sel withArgsArray:(NSArray *)args { 
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature: 
         [self methodSignatureForSelector:sel]]; 
    [inv setSelector:sel]; 
    [inv setTarget:self]; 
    for (int i = 0; i < args.count; i++) { 
    id a = [args objectAtIndex:i]; 
    [inv setArgument:&a atIndex:2 + i]; // 0 is target, 1 is cmd-selector 
    } 
    [inv invoke]; 

    NSNumber *r; 
    [inv getReturnValue:&r]; 
    return r; 
} 
@end 

그리고 다음과 같이 사용 :

#import "NSObject+performSelectorWithArgs.h" 

@interface SomeClass : NSObject 
@end 

@implementation SomeClass 
- (NSNumber *)withA:(NSNumber *)a withB:(NSNumber *)b { 
    return [NSNumber numberWithInt:a.intValue + b.intValue]; 
} 
@end 

- (void)someMethod { 
    SomeClass *a = [[SomeClass alloc] init]; 
    SEL sel = @selector(withA:withB:); 
    NSArray *args = [NSArray arrayWithObjects: 
        [NSNumber numberWithInt:2], 
        [NSNumber numberWithInt:3], 
        nil]; 
    NSNumber *r = [a performSelector:sel withArgsArray:args]; 
    NSLog(@"%d", r.intValue); 
} 

이 같은 뭔가를 선택하는 경우 q를 물릴 수 있으므로 NSInvocation의 작동 방식을 실제로 읽어 보는 것이 좋습니다. uite 하드. 모든 인수와 반환 값이 객체가 아니더라도이 작업을 수행 할 수 있는지 여부는 확실하지 않습니다.

+0

선택기는 객체/클래스로 묶여 있습니까? 그렇지 않다면, 당신의 예제를 다시 작성하여 객체/클래스 인수를 포함시킬 수 있습니까? – mcandre

+0

이런 뜻이야? 어쨌든 선택자가 클래스에 의존한다고 생각하지 않습니다. 메시지의 임의의 선택자를 인스턴스로 보내고 인스턴스를 처리 할 수 ​​있기를 바랍니다. 하지만 실제로 이해할 수없는 한 가지는 리턴 타입이 처리되는 것을 보여 주며, 'NSInvocation'을 사용할 때는 항상 이음새가'void * '가됩니다. –

+0

그러나'void *'반환 값을 사용하여 객체 참조를 반환 할 수 있습니다. –

2

NSArray에는 enumerateObjectsUsingBlock:enumerateObjectsWithOptions:usingBlock:가 있습니다.

[[NSArray arrayWithObjects:@"a", @"b", @"c", nil] 
enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    NSLog(@"%d: %@", idx, obj); 
}]; 
+0

아닙니다. 문서에서 : "블록은 세 가지 인수를 취합니다." 이후의 함수는 블록에 특수한 3 차 변수 구문을 사용하지 않아도됩니다. – mcandre

+0

아, 이제 알겠습니다. 새로운 대답을 올렸습니다. –