【问题标题】:Implementing a Dispatch Table in Objective-C: how to declare an array of selectors在 Objective-C 中实现调度表:如何声明一个选择器数组
【发布时间】:2011-12-19 15:04:00
【问题描述】:

我正在尝试实现一个调度表,以便可以使用以下示例代码调用选择器:

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

我正在尝试存储影响 API 的哪个方法被调用的用户偏好。现在,我使用选择器的字符串名称并使用 NSSelectorFromString,但这有点乱。如果我使用调度表,那么我可以存储一个枚举。

如何在 Objective-C 中创建选择器数组或调度表?

编辑:

当我尝试将选择器数组设置为属性时,编译器会报错。 @property SEL[] 不会编译。

编辑2:

我正在使用my KosherCocoa API 库,我想根据保存的用户设置一次调用一个方法。我正在保存和读取 Plist 文件。

【问题讨论】:

标签: objective-c dispatch dispatch-table


【解决方案1】:

您可以使用SEL 类型来保存选择器。简单地说:

SEL dispatchTable[3] = { @selector(doThis:), 
                         @selector(doThat:), 
                         @selector(doTheOther:) 
                       };

对于您的编辑,请使用 NSArray/NSDictionary/etc 的选择器作为您的属性。不允许在 Objective C 中使用 C 数组作为属性;它们不是受支持的类型之一(它们是 ObjC 对象、CF 类型和基本 C 'Plain Old Data' 类型。)

好的,在我们下面的 cmets 中,您需要将选择器包装在 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];

因此,现在您的表是一个存储为属性或 ivar 的 objc 容器,您使用 NSValueSEL 指针与 valueWithPointer: 包装在一起,并使用 SEL 取出 pointerValue

【讨论】:

  • 其实在数组中使用选择器是有问题的。似乎不起作用。我收到“不兼容的指针”警告。
  • 你能用一些代码发布一个问题的例子吗?声明选择器数组没有错。
  • 显然取决于范围。当我将您的数组粘贴到一个方法中时,这很好,但是如果我将它放入实现中,在方法之外,它会抱怨。
  • 谢谢,但是我如何为一百个指针做到这一点。这很快就会变得一团糟,不是吗?
  • 一百个选择器?你想建立什么?以防万一不是很明显,您不需要显式声明一百个 SEL 变量;你可以动态地做整个事情: [table addObject:[NSValue valueWithPointer:@selector(doThis:)]];但最终如果你有一百个选择器,你将不得不在某个地方命名它们。
【解决方案2】:

我建议使用 NSInvocation 而不是选择器。它们更加灵活,因为您可以向许多对象发送相同的调用,并且可以随时更改其属性。

【讨论】:

  • 肯定比其他方法贵。 非常昂贵?你会怎么判断呢?
  • 我想了解更多来自@Moshe 的信息;正确的解决方案取决于问题。
  • 好吧,也许对于一百个选择器来说,使用 NSInvocation 并不是一个好主意。
【解决方案3】:

一种方法是使用 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; 有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
相关资源
最近更新 更多