在Objective-C中实现调度表:如何声明一个选择器数组。

3

我正试图实现一个调度表,这样我就可以使用以下示例代码调用选择器:

NSInteger i = 2;
[myObject performSelector:selectors[i]];

我希望储存用户偏好,以影响API中调用的方法。现在,我使用选择器的字符串名称并使用NSSelectorFromString,但这有点混乱。如果我使用dispatch表,那么我可以存储一个枚举。如何在Objective-C中创建一个选择器数组或dispatch表?编辑:当我尝试将选择器数组设置为属性时,编译器会出错。@property SEL[]无法编译。我正在使用my KosherCocoa API库,并想基于保存的用户设置一次调用单个方法。我正在保存到和读取Plist文件。

也许使用策略模式会更适合你,而不是那样做。http://en.wikipedia.org/wiki/Strategy_pattern - Nick Toumpelis
3个回答

3
您可以使用SEL类型来保存选择器。简单地说:
SEL dispatchTable[3] = { @selector(doThis:), 
                         @selector(doThat:), 
                         @selector(doTheOther:) 
                       };

对于您的编辑,建议使用NSArray/NSDictionary等选择器作为属性。在Objective C中,不允许将C数组用作属性;它们不是受支持的类型之一(受支持的类型包括ObjC对象、CF类型和基本的C“Plain Old Data”类型)。
好的,在我们下面的评论中,您需要将选择器包装在NSValue中,以便可以在objc容器中使用它(因为SEL是一个C指针类型)。
NSMutableArray * dispatchTable2 = [[NSMutableArray alloc] initWithCapacity:3];
SEL selIn = @selector(doThis:);

// Wrap the selector in an NSValue instance
[dispatchTable2 addObject:[NSValue valueWithPointer:selIn]];

// On extracting:
NSValue * valOut = [dispatchTable2 objectAtIndex:0];
SEL selOut = [[dispatchTable2 objectAtIndex:0] pointerValue];
[anObject performSelector:selOut];

现在你的表格是一个存储为属性或实例变量的Objective-C容器,你可以使用NSValueSEL指针包装起来,使用valueWithPointer:方法,而使用pointerValue方法则可以取出SEL


实际上,在数组中使用选择器存在问题。似乎不起作用。我收到了一个“不兼容指针”的警告。 - Moshe
2
你能否提供一些代码示例来说明问题吗?声明选择器数组没有任何问题。 - Tim
根据范围而定,显然。当我将你的数组粘贴到一个方法中时,它是正常的,但如果我把它放在实现代码之外,就会发生错误。 - Moshe
谢谢,但是如果我要对一百个指针执行此操作,该怎么办?那会变得非常混乱,不是吗? - Moshe
一百个选择器?你在尝试构建什么?以防不是完全明显的是,你不需要显式声明一百个SEL变量;你可以动态地完成整个过程:[table addObject:[NSValue valueWithPointer:@selector(doThis:)]];但最终如果你有一百个选择器,你总得给它们命名。 - Tim

2

我建议使用NSInvocation而不是选择器。它们更加灵活,因为您可以将相同的调用发送到多个对象,并且可以在进行操作时更改其属性。


比其他方法更昂贵,当然。非常昂贵?你如何评价它? - Nick Toumpelis
1
我想从@Moshe那里看到更多的信息;正确的解决方案取决于问题。 - Tim
好的,或许对于一百个选择器来说,使用NSInvocation并不是一个很好的主意。 - Nick Toumpelis

1
一种方法是使用一个NSStrings数组,然后在运行时将其转换为SEL,如果这样可以增加可读性的话。
NSString *selectors[] = { ... } 

[myObject performSelector:NSSelectorFromString(selectors[i])];

如果要将其用作属性,请使用

@property(nonatomic, assign) NSString **selectors;

仅供记录,我尝试使用@property(nonatomic, assign) NSString **selectors;,但是它会报错pointer to non-const type NSString *with no explicit ownership,而@property(nonatomic, assign) void **selectors;则可以正常工作。 - geekay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接