动态方法解析
这一章解释了怎样动态的提供一个方法的实现。
动态方法解析
当你想动态的提供一个方法的实现的时候,用 @dynamic
来定义一个属性
@dynamic propertyName;
这将告诉编译器,和这个属性关联的方法将会动态的提供。
你可以用使用 resolveInstanceMethod:
和 resolveClassMethod:
来动态的实现一个实例方法或者类方法的方法选择器
Objective-C
方法是一个简单的 C
函数,至少包含两个参数 self
和 _cmd
,你可以使用 class_addMethod
来为一个类添加一个方法。比如下边的函数
void dynamicMethodIMP(id self, SEL _cmd) {
// implementation ....
}
你可以使用 resolveInstanceMethod:
来动态的为一个类添加方法。
@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)aSEL
{
if (aSEL == @selector(resolveThisMethodDynamically)) {
class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
return YES;
}
return [super resolveInstanceMethod:aSEL];
}
@end
消息转发Message Forwarding和方法动态解析在很大程度上是相互配合的,在转发机制生效之前,一个类是可以动态的解析方法的。如果 respondsToSelector: 或者 instancesRespondToSelector: 被执行的话,动态方法解析提供一个机会为这个 selector
提供一个 IMP
,如果你实现了 resolveInstanceMethod: 但是想指定一个被消息转发机制转发的方法选择器,你应该返回 NO
。
动态加载
当程序运行的时候,Objective-C
可以动态的加载链接新的类或者类别。这些新的代码和原来类和类别是一样的。
动态加载可以做很多不同的事。例如,系统的各个模块都是动态加载的。
在 Cocoa
运行环境中,动态加载经常被用来动态的定制应用。可以在运行时添加模块,就像在 IB
中加载自定义调色板,在 OS X
中加载个人偏好设置一样。可动态加载的模块扩展了你的应用的能力。你提供框架,别人提供代码。
尽管 runtime
系统可以动态的加载 Objective-C
模块,(在 objc/objc-load.h
中的 objc_loadModules
), Cocoa
框架中的 NSBundle
提供了更加方便快捷的动态加载方法(面向对象的方式)。
在 NSBundle 你可以看到更多的信息。