我正在尝试在Objective-C中构建一个NSArray方法.
(我在这里要完成的是C中的以下内容)
typedef (void)(*handler)(int command);
void handleCommandA(void) { ... }
void handleCommandB(void) { ... }
static const handler handler_table[10] = {
handleCommandA, handleCommandB, handleCommandC
};
Run Code Online (Sandbox Code Playgroud)
我必须将它移植到Objective-C,我不知道如何在编译时构建一个函数指针数组(在Objective-c世界,类方法中).
在Objective-C中,我有以下内容.
- (void)handleCommandA { ... }
- (void)handleCommandB { ... }
/* Now how to add above 2 functions into NSArray? */
NSArray *handler_table = [NSArray arrayWithObjects:... ]; /* This doesn't seem to work. */
Run Code Online (Sandbox Code Playgroud)
And*_*ant 29
这里的问题是,要绑定这些函数,您必须使用返回SEL类型的selector关键字.这是指针类型,而NSArray存储对象.
你有三个选择;
第二个可能更好,为此您可以使用NSValue类来保存选择器结果.例如;
NSValue* selCommandA = [NSValue valueWithPointer:@selector(handleCommandA:)];
NSValue* selCommandB = [NSValue valueWithPointer:@selector(handleCommandB:)];
NSArray *handler_table = [NSArray arrayWithObjects:selCommandA, selCommandB, nil ];
Run Code Online (Sandbox Code Playgroud)
当您从阵列中检索到正确的条目时,要转换回来,您会这样做;
SEL mySelector = [selCommand pointerValue];
[someObject performSelector:mySelector];
Run Code Online (Sandbox Code Playgroud)
(注意我假设你的objective-c语法中的这些用作对象的方法,而不是全局函数.如果你想在全局使用它们,那么你应该像在C中那样编写它们.)
另一种选择是将命令方法形式化为协议.这允许您编写可以在任何实现该协议的对象上工作的功能,并且编译器将提供比您只是调用选择器更多的检查.
例如
// some header
@protocol CommandHandler
@required
-(void) handleCommandA;
-(void) handleCommandB;
@end
// some other header
@interface someClass : NSObject<CommandHandler>
{
// you will receive compiler warnings if you do not implement the protocol functions
}
Run Code Online (Sandbox Code Playgroud)
然后编写处理和调度代码以使用"CommandHandler"类型的对象.例如
-(void) registerForCommands:(CommandHandler*)handler
Run Code Online (Sandbox Code Playgroud)
使用NSValue.
例如:
NSArray* handlers = [NSArray arrayWithObjects:[NSValue valueWithPointer:handleA] ... ];
Run Code Online (Sandbox Code Playgroud)
然后访问:
handleptr* handle = (handlerptr*)[[handlers objectAtIndex:0] pointerValue];
handle(foo_bar);
Run Code Online (Sandbox Code Playgroud)