目標C是否有像Smalltalk的Block valueWithArguments
這樣的功能?如何將參數列表應用於Objective C中的塊?
我正在尋找一個函數像一個簽名:
apply(^(), NSArray* args)
另外,有一個方法來調用過的參數列表中選擇?
目標C是否有像Smalltalk的Block valueWithArguments
這樣的功能?如何將參數列表應用於Objective C中的塊?
我正在尋找一個函數像一個簽名:
apply(^(), NSArray* args)
另外,有一個方法來調用過的參數列表中選擇?
有了塊,你可能需要做一些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);
}
如果你選擇做這樣的事情我建議你真正閱讀NSInvocation
如何工作,因爲它可以咬很難。不確定是否可以做到這一點,而不要求所有參數和返回值都是對象。
NSArray
有方法enumerateObjectsUsingBlock:
和enumerateObjectsWithOptions:usingBlock:
是你在找什麼?
[[NSArray arrayWithObjects:@"a", @"b", @"c", nil]
enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%d: %@", idx, obj);
}];
不完全。從文檔:「塊需要三個參數。」我之後的函數不需要塊使用特殊的三級變量語法。 – mcandre
現在我看到了,發佈了一個新的答案。 –
選擇器是否與其對象/類綁定?如果不是,你可以重寫你的例子來包含一個對象/類參數嗎? – mcandre
您的意思是?我不認爲選擇器依賴於類,您可以將消息中的任何選擇器發送給實例,並希望它能夠處理它。但有一件事我不明白,它顯示返回類型是處理的,當使用'NSInvocation'時,接縫永遠是'void *'。 –
但是你可以使用'void *'返回值來返回一個對象引用。 –