Objective C是否具有类似Smalltalk的Block valueWithArguments
?
我正在寻找一个带有签名的函数:
apply(^(), NSArray* args)
或者,有没有办法在参数列表上调用选择器?
答案 0 :(得分:2)
NSArray
方法enumerateObjectsUsingBlock:
和enumerateObjectsWithOptions:usingBlock:
是您要找的?
[[NSArray arrayWithObjects:@"a", @"b", @"c", nil]
enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%d: %@", idx, obj);
}];
答案 1 :(得分: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);
}
如果你选择做这样的事情,我建议你真正了解NSInvocation
的工作方式,因为它可以咬得很厉害。不确定是否可以这样做而不要求所有参数和返回值都是对象。