【问题标题】:respondsToSelector and class_getInstanceMethodrespondsToSelector 和 class_getInstanceMethod
【发布时间】:2013-04-10 18:37:39
【问题描述】:

在内部,respondsToSelector 所做的不仅仅是找出class_getInstanceMethod 是否返回非零吗?

responsToSelector 本质上是 class_getInstanceMethod 的包装器吗?像这样:

- (BOOL)respondsToSelector:(SEL)sel {
  return class_getInstanceMethod(self, sel) != nil;
}

【问题讨论】:

  • 在苹果的开源 NSObject implementation 中,respondsToSelector: 在第 1472 行,看起来像这样:- (BOOL)respondsToSelector:(SEL)sel { if (!sel) return NO; return class_respondsToSelector([self class], sel); }
  • 乔希,这太棒了 - 来源。
  • 为了在@JoshCaswell 评论上更进一步,实际实现在objc-class.mmclass_respondsToSelector @ 729 行结束,它调用lookUpMethod@916 行,这是一个很好的99 行阅读
  • Paul.s. 1+ 谢谢。
  • @JoshCaswell 你能把你的答案放在底部吗?

标签: objective-c cocoa-touch objective-c-runtime


【解决方案1】:

在 Apple 的开源 NSObject implementation 中,respondsToSelector: 位于第 1472 行,如下所示:

- (BOOL)respondsToSelector:(SEL)sel { 
    if (!sel) return NO; 
    return class_respondsToSelector([self class], sel); 
}

class_respondsToSelector()又在objc-class.mm的第729行:

BOOL class_respondsToSelector(Class cls, SEL sel)
{
    IMP imp;

    if (!sel  ||  !cls) return NO;

    // Avoids +initialize because it historically did so.
    // We're not returning a callable IMP anyway.
    imp = lookUpMethod(cls, sel, NO/*initialize*/, YES/*cache*/, nil);
    return (imp != (IMP)_objc_msgForward_internal) ? YES : NO;
}

【讨论】:

    【解决方案2】:

    -respondsToSelector: 返回一个BOOL,基本上表示class_getInstanceMethod() 是否会返回一个值。这是否回答你的问题?

    -respondsToSelector:-performSelector:* 的变体之一配对在传统的Objective-C 代码中更为惯用;很少看到(或需要)直接调用运行时。

    编辑:实际实现可能基于调用class_respondsToSelector(),但我希望该运行时方法的实现与您的代码 sn-p 没有根本不同。

    【讨论】:

    • 对不起,我把问题详细阐述了。
    • 查看更新。我想你基本上是对的。尽管实现的方式有多种,但这是基本的逻辑功能。
    • 其实我觉得在涉及到转发的时候可能会有细微的差别。如果你实现了类似here 中描述的转发行为(例如伪造多重继承),你最终可能会导致respondsToSelector:class_getInstanceMethod 出现分歧。
    • @GabrielePetronella 该文档特别指出-respondsToSelector: 的标准实现为转发调用返回NO。如果您在这种情况下遵循覆盖-respondsToSelector: 的建议,那么是的,行为会有所不同,但这并不奇怪......
    • 我知道,我说的是你如果把它改成镜像你的转发算法,就可以解绑这两种方法的结果。因此,如果您不是该类的所有者,您不能相信它们总是会返回相同的结果
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多