动态方法解析(Dynamic Method Resolution)

本章介绍如何动态地提供一个方法的实现。

动态方法解析(Dynamic Method Resolution)

有些情况你可能像动态地提供一个方法的实现。例如,Objective-C声明属性的特性(参阅The Objective-C Programming Language中的声明属性)包含@dynamic指令:

@dynamic propertyName;

这告诉编译器该属性关联的方法将会动态地提供。

你可以实现resolveInstanceMethod:resolveClassMethod:方法分别为为一个实例和类方法的给定选择器动态地提供实现。

Objective-C方法是一个最少有两个参数(self和_cmd)的C函数。可以使用class_addMethod函数给一个类添加函数作为方法。因此,给出下面的函数:

void dynamicMethodIMP(id self, SEL _cmd) {
    // implementation ....
}

你可以使用resolveInstanceMethod:动态地添加它到一个类作为方法(称为resolveThisMethodDynamically),像这样:

@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:,动态方法解析器有机会首先为选择器提供IMP。你如你实现了resolveInstanceMethod:方法但是希望特定的选择器通过转发机制实际转发,则为这些选择器返回NO。

动态加载(Dynamic Loading)

Objective-C程序在运行时可以加载并链接新的类和类别。新代码被合并到程序中,并且跟最开始加载的类和类别处理方式相同。

动态加载可以被用来做很多不同的事情。例如,系统偏好设置应用程序中的各个模块都是动态加载的。

在Cocoa环境下,动态加载通常被用来允许应用程序定制。其他人可以编写程序在运行时加载的模块-就像Interface Builder加载自定义调色板一样,OS X系统偏好设置应用程序加载自定义首选项模块。可加载模块拓展了应用程序可以执行的操作。他们以你允许的方法为其做出贡献,但无法预期或定义你自己。你提供了框架,但其他人提供了代码。

尽管在Mach-O文件(objc_loadModules,在objc/objc-load.h中定义)中有一个运行时函数负责执行Objective-C模块的动态加载,Cocoa的NSBundle类为动态加载提供了更便捷的接口-一个是面向对象并与相关服务相结合。有关NSBundle类及其用法的信息,请参阅Foundation framework reference中的NSBundle类规范。有关Mach-O文件的信息,请参阅OS X ABI Mach-O文件格式参考。

results matching ""

    No results matching ""