【问题标题】:How are protocols internally implemented?协议是如何在内部实现的?
【发布时间】:2012-02-12 09:40:33
【问题描述】:

据我所知,Objective-C 中的类是以 C 结构形式存储的。 协议是如何实现的?

我想简单地理解一下。

[NSObject conformsToProtocol:] 做什么来检查一个类是否符合协议?

是否有一个协议的表或数据结构可以告诉协议中有哪些选择器?

注意:此处的术语“协议”用于指代 Objective C 构造而不是网络协议。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    如果您查看Objective-C Runtime Reference,您会发现有几个函数允许您检索和检查所谓的Protocol 结构的内容。

    这些结构允许访问 Protocol 对象包含的内容,并且其属性名称应该可以推断出它们的基本目的是什么。

    Protocol 包含的部分成员如下:

    1. objc_method_description 结构的列表。
    2. objc_property_t 结构的列表。

    当然还有一个名为 protocol_getName 的方法,它会为您提供协议本身的名称。

    我认为这应该足以让您自己推断这些协议是如何由 Objective-C 编译器 + 运行时实现的。

    我对它们如何实际实现的想法是,编译器在编译时将这些所谓的@protocol 声明转换为 C 结构,而诸如 conformsToProtocol: 之类的 Objective-C 方法只需对成员进行比较由@protocol 语言构造生成的传入结构。

    因此,您可以这样做:

    @protocol BlahProtocol <NSObject>
    
    -(void)blahMethod;
    @property (nonatomic, strong) id blahProperty;
    
    @end
    
    //...
    Protocol *blah = objc_getProtocol("BlahProtocol");
    struct objc_method_description blahMethodDescription = protocol_getMethodDescription(blah, @selector(blahMethod), NO, YES);
    
    NSLog(@"%s %s", blahMethodDescription.name, blahMethodDescription.types);
    
    objc_property_t blahProperty = protocol_getProperty(blah, "blahProperty", NO, YES);
    
    NSLog(@"%s", property_getAttributes(blahProperty));
    

    【讨论】:

    • conformsToProtocol: 不关心协议中的内容。它只是检查协议是否在类或其任何超类的协议列表中(根据class_copyProtocolList())
    【解决方案2】:

    协议通过指定调用某个方法来工作。您询问对象是否“respondsToSelector”,以检查它是否实现了特定方法,然后通过调用该方法来调用它。

    【讨论】:

      猜你喜欢
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      相关资源
      最近更新 更多