如何在Objective-C中构建类方法的NSArray(或NSMutableArray)?

如何在Objective-C中构建类方法的NSArray(或NSMutableArray)?,objective-c,Objective C,我正在尝试在中构建一系列方法 (我在这里试图实现的是类似于C中的以下内容) 我必须把它移植到Objective-C,我不知道怎么做 构建函数指针数组(在Objective-c世界中, 类方法)在编译时 在Objective-C中,我有以下内容 - (void)handleCommandA { ... } - (void)handleCommandB { ... } /* Now how to add above 2 functions into NSArray? */ NSArray *han

我正在尝试在中构建一系列方法

(我在这里试图实现的是类似于C中的以下内容)

我必须把它移植到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. */

这里的问题是,要绑定这些函数,必须使用返回SEL类型的selector关键字。这是指针类型,而NSArray存储对象

因此,你有三个选择

  • 使用常规C类型数组
  • 将函数折叠到将调用它们的NSObject派生类中
  • 使用协议
  • 第二个可能更好,为此,可以使用NSValue类保存选择器结果。例如,

    NSValue* selCommandA = [NSValue valueWithPointer:@selector(handleCommandA:)];
    NSValue* selCommandB = [NSValue valueWithPointer:@selector(handleCommandB:)];
    
    NSArray *handler_table = [NSArray arrayWithObjects:selCommandA, selCommandB, nil ];
    
    当您从数组中检索到正确的条目时,要将其转换回,您需要执行以下操作:

    SEL mySelector = [selCommand pointerValue];
    [someObject performSelector:mySelector];
    
    (注意,我假设从objective-c语法来看,它们是用作对象上的方法,而不是全局函数。如果您希望全局使用它们,那么您应该像在普通c中那样编写它们。)

    另一种选择是将命令方法形式化为协议。这允许您编写在实现该协议的任何对象上都能工作的功能,并且编译器将提供比您仅调用选择器更多的检查

    例如


    在Objective-C中,您不会传递方法;您可以传递选择器,它们基本上是方法的规范名称。然后,要使对象响应选择器消息,将其发送到
    performSelector:
    。例如:

    NSString *exampleString = [NSString stringWithString:@"Hello"];
    SEL methodName = @selector(stringByAppendingString:);
      // ^This is the selector. Note that it just represents the name of a
      //  message, and doesn't specify any class or implementation
    NSString *combinedString = [exampleString performSelector:methodName withObject:@" world!"];
    
    NSArray* handlers = [NSArray arrayWithObjects:[NSValue valueWithPointer:handleA] ... ];
    
    您需要的是生成一个NSString数组,其中包含您感兴趣的选择器的名称。您可以使用函数
    NSStringFromSelector()
    执行此操作。然后,当您想要使用它们时,在字符串上调用
    NSSelectorFromString()
    ,以获取原始选择器并将其传递给相应对象的
    性能选择器:
    。(如上面的示例所示,接收器不是在选择器中编码的-只是方法名称-因此您可能还需要存储接收器。)

    使用NSValue

    例如:

    NSString *exampleString = [NSString stringWithString:@"Hello"];
    SEL methodName = @selector(stringByAppendingString:);
      // ^This is the selector. Note that it just represents the name of a
      //  message, and doesn't specify any class or implementation
    NSString *combinedString = [exampleString performSelector:methodName withObject:@" world!"];
    
    NSArray* handlers = [NSArray arrayWithObjects:[NSValue valueWithPointer:handleA] ... ];
    
    然后访问:

    handleptr* handle = (handlerptr*)[[handlers objectAtIndex:0] pointerValue];
    handle(foo_bar);
    

    我更喜欢使用字符串而不是指针,因为这会使调试更容易。看看NSStringFromSelector()和NSSelectorFromString()。使用选择器的小更正实际上如下:[someObject performSelector:mySelector];
    handleptr* handle = (handlerptr*)[[handlers objectAtIndex:0] pointerValue];
    handle(foo_bar);