【问题标题】:Check if a method exists检查方法是否存在
【发布时间】:2010-04-28 20:24:37
【问题描述】:

有什么方法可以测试 Objective-C 中是否存在方法?

我正在尝试添加一个守卫,以在调用它之前查看我的对象是否具有该方法。

【问题讨论】:

  • 首先还有一个问题是这是否是正确的方法,因为 Objective-C 类可以响应他们没有声明的选择器(通过- forwardInvocation:)。

标签: objective-c


【解决方案1】:
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}

【讨论】:

    【解决方案2】:

    还有静态消息instancesRespondToSelector:(SEL)selector 你可以这样称呼它:

    [MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]
    

    或者像这样:

    [[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]
    

    如果您想根据 this 调用一个构造函数或另一个构造函数(我的意思是,在拥有实例本身之前),这可能会很有用。

    【讨论】:

    • instanceRespondToSelector 与 respondsToSelector 有什么不同?
    • 主要区别在于一个是实例消息(用于测试确定的实例消息是否存在),另一个是类消息(用于测试确定的类消息是否存在)。跨度>
    • +1 对于 [MyClass instancesRespondToSelector]。我在初始化创建方法中需要它:当子类化可能需要调用一个超级初始化方法而不是其他方法(不推荐使用的方法)时,因为尚未创建 self 并且 respondsToSelector 将始终返回 NO。
    【解决方案3】:

    使用respondsToSelector:。来自documentation:

    respondsToSelector:

    返回一个布尔值,指示接收者是实现还是继承了可以响应指定消息的方法。

    - (BOOL)respondsToSelector:(SEL)aSelector
    

    参数
    aSelector - 标识消息的选择器。

    返回值
    如果接收者实现或继承了可以响应aSelector的方法,则为YES,否则为NO。

    【讨论】:

      【解决方案4】:

      你正在寻找respondsToSelector:-

      if ([foo respondsToSelector: @selector(bar)] {
        [foo bar];
      }
      

      正如Donal says 上面所说的,foo 可以绝对处理接收条形选择器。但是,如果 foo 是将 bar 转发到将接收 bar 消息的某个底层对象的代理,那么 respondsToSelector: 将告诉您 NO,即使该消息将被转发到响应 bar 的对象。

      【讨论】:

        【解决方案5】:

        使用 respondsToSelector 检查选择器通常仅适用于委托方法。您不应该将 forwardInvocation 或代理用于委托方法。如果您需要在其他情况下使用 respondsToSelector,您可能需要确保没有更合适的方式来设计您的程序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-14
          • 2018-08-04
          • 1970-01-01
          • 2011-11-26
          • 2014-04-11
          • 1970-01-01
          相关资源
          最近更新 更多