我知道如何使用SEL
在编译时创建@selector(MyMethodName:)
,但我想要做的是从NSString
动态创建一个选择器。这甚至可能吗?
我能做什么:
SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];
我想做什么:(伪代码,这显然不起作用)
SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];
我一直在搜索Apple API文档,但没有找到一种不依赖于编译时@selector(myTarget:)
语法的方法。
答案 0 :(得分:180)
我不是Objective-C程序员,只是一个同情者,但也许NSSelectorFromString就是你所需要的。它提到Runtime Reference中的明确表示您可以使用它将字符串转换为选择器。
答案 1 :(得分:40)
根据XCode文档,你的伪代码基本上是正确的。
使用@selector()指令在编译时为SEL变量赋值是最有效的。但是,在某些情况下,程序可能需要在运行时将字符串转换为选择器。这可以使用NSSelectorFromString函数完成:
setWidthHeight = NSSelectorFromString(aBuffer);
编辑:糟糕,太慢了。 :P
答案 2 :(得分:11)
我不得不说它比以前的受访者的答案可能暗示的更复杂 ...如果你确实想要创建一个选择器。 ..而不只是“召唤一个”,你“已经四处走动”......
你需要创建一个将由“new”方法调用的函数指针..所以对于像[self theMethod:(id)methodArg];
这样的方法,你要写...
void (^impBlock)(id,id) = ^(id _self, id methodArg) {
[_self doSomethingWith:methodArg];
};
然后你需要动态生成IMP
块,这次,传递,“自我”,SEL
以及任何参数......
void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);
并将其添加到您的类中,以及整个吸盘的准确方法签名(在本例中为"v@:@"
,void return,object caller,object argument)
class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");
的一些很好的例子
答案 3 :(得分:4)
我知道很久以前就已经回答了这个问题,但我仍想分享。这也可以使用sel_registerName
来完成。
问题中的示例代码可以像这样重写:
SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];