動態方法解析
這一章解釋了怎樣動態的提供一個方法的實現。
動態方法解析
當你想動態的提供一個方法的實現的時候,用 @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 你可以看到更多的信息。