【问题标题】:How can I dynamically create a selector at runtime with Objective-C?如何在运行时使用 Objective-C 动态创建选择器?
【发布时间】:2010-09-11 21:01:27
【问题描述】:

我知道如何在编译时使用@selector(MyMethodName:) 创建一个SEL,但我想做的是从NSString 动态创建一个选择器。这甚至可能吗?

我能做什么:

SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];

我想做什么:(伪代码,这显然行不通)

SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];

我一直在搜索 Apple API 文档,但没有找到不依赖编译时 @selector(myTarget:) 语法的方法。

【问题讨论】:

    标签: objective-c cocoa dynamic


    【解决方案1】:

    我不是 Objective-C 程序员,只是一个同情者,但也许 NSSelectorFromString 是你需要的。 Runtime Reference 中明确提到您可以使用它将字符串转换为选择器。

    【讨论】:

    • 我需要复习一下我的 Google-fu。这正是我一直在寻找的(或者可能不是)。
    • 嗯,自从我几天前阅读了 Objective-C 2.0 文档以来,我的书签中仍然有链接飞来飞去。
    【解决方案2】:

    根据 XCode 文档,您的伪代码基本上是正确的。

    在编译时使用 @selector() 指令为 SEL 变量赋值是最有效的。但是,在某些情况下,程序可能需要在运行时将字符串转换为选择器。这可以通过 NSSelectorFromString 函数来完成:

    setWidthHeight = NSSelectorFromString(aBuffer);

    编辑:糟糕,太慢了。 :P

    【讨论】:

    • NSStringFromSelector(@"doWork") 以另一种方式转换(仅供参考)
    • 我想你的意思是,NSStringFromSelector(@selector(doWork))
    • 那个选择器应该做什么?我们不应该指定一个块或其他东西吗?
    【解决方案3】:

    我不得不说它比之前的回答可能暗示的要复杂一点......如果你真的想创建一个选择器。 .. 不只是“打电话给”你“已经躺着”...

    您需要创建一个将由您的“新”方法调用的函数指针。所以对于像[self theMethod:(id)methodArg]; 这样的方法,您应该编写...

    void (^impBlock)(id,id) = ^(id _self, id methodArg) { 
         [_self doSomethingWith:methodArg]; 
    };
    

    然后您需要动态生成IMP 块,这一次,传递“self”、SEL 和任何参数...

    void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);
    

    并将其添加到您的类中,以及整个傻瓜的准确方法签名(在本例中为"v@:@",无效返回,对象调用者,对象参数)

     class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");
    

    你可以看到这种runtime shenanigans, in one of my repos, here.的一些很好的例子

    【讨论】:

      【解决方案4】:

      我知道这个问题很久以前就有了,但我仍然想分享。这也可以使用sel_registerName 来完成。

      问题中的示例代码可以这样改写:

      SEL selector = sel_registerName("doWork:");
      [myobj respondsToSelector:selector];
      

      【讨论】:

      • 实际上,@torsten-marek 提到的NSSelectorFromString 在后台使用了sel_registerNameappledev:“NSSelectorFromString 将 aSelectorName 的 UTF-8 编码字符表示传递给 sel_registerName 并返回该函数返回的值”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-04
      • 2020-09-16
      相关资源
      最近更新 更多