【发布时间】:2014-02-07 01:56:09
【问题描述】:
我正在编写几个使用 Objective-C 运行时库的类。这包括在运行时根据其名称检索协议定义。但是,似乎没有被类明确采用或在代码中使用 @protocol(ProtocolName) 引用的协议被排除在编译之外并且在运行时不可用。
例子:
@protocol MyProtocol <NSObject>
-(void)doSomething;
@end
//代码中的其他地方
Protocol *protocol = NSProtocolFromString(@"MyProtocol");
// ^ value of "protocol" will be nil when I run the application!
//但是,如果我使用,请执行以下操作:
Protocol *whyDoIHaveToDoThis = @protocol(MyProtocol);
Protocol *protocol = NSProtocolFromString(@"MyProtocol");
// ^ value of "protocol" will now be a pointer as expected when I run the application!
有谁知道这是为什么,甚至更好的是,如何强制编译器包含在编译时未使用但我稍后希望在运行时可用的协议定义?
【问题讨论】:
-
这就是它的工作方式。如果没有类采用该协议,你如何使用它?
-
这个答案可能会有所帮助:stackoverflow.com/a/11533804/342620
-
这是意料之中的。编译器不会为协议声明发出元数据,并在使用该协议的任何文件中发出元数据的副本(通过采用它或通过编写
@protocol(ProtoName)表达式。 -
感谢所有的 cmets。 @Hot Licks - 可以使用 class_addProtocol() 等函数在运行时分析和采用协议。对于需要在运行时与未知的“外部”代码交互的库、插件和其他类型的代码,即使在编译时没有内部对象采用它们,也可以动态查找协议定义,这一点很重要。我真的很惊讶协议定义被这样剥离,而 Objective-C 是一种动态语言,旨在能够处理未知类型,而这首先是协议的主要用途。
-
但是协议主要是给编译器的文档,告诉它哪些方法是可用的——它没有真正的运行时函数。 class_copyMethodList 会告诉你运行时有哪些方法。
标签: ios objective-c protocols llvm objective-c-runtime