load
メッセージ_
ランタイムload
は、クラスオブジェクトがプロセスのアドレス空間にロードされた直後に、各クラスオブジェクトにメッセージを送信します。プログラムの実行可能ファイルの一部であるクラスの場合、ランタイムload
はプロセスの存続期間の非常に早い段階でメッセージを送信します。共有(動的にロードされる)ライブラリにあるクラスの場合、ランタイムは、共有ライブラリがプロセスのアドレス空間にロードされた直後にロードメッセージを送信します。
さらに、ランタイムはload
、クラスオブジェクト自体がメソッドを実装している場合にのみ、クラスオブジェクトに送信しますload
。例:
@interface Superclass : NSObject
@end
@interface Subclass : Superclass
@end
@implementation Superclass
+ (void)load {
NSLog(@"in Superclass load");
}
@end
@implementation Subclass
// ... load not implemented in this class
@end
ランタイムはload
メッセージをSuperclass
クラスオブジェクトに送信します。からメソッドを継承していても、クラスオブジェクトにメッセージを送信しません。load
Subclass
Subclass
Superclass
ランタイムは、クラスのすべてのスーパークラスオブジェクト(これらのスーパークラスオブジェクトが実装されている場合)およびリンク先の共有ライブラリ内のすべてのクラスオブジェクトにメッセージload
を送信した後、クラスオブジェクトにメッセージを送信します。ただし、自分の実行可能ファイル内の他のどのクラスがまだ受信しているかはわかりません。load
load
load
プロセスがそのアドレス空間にロードするすべてのクラスは、プロセスがそのクラスを他に使用するかどうかに関係なく、メソッドをload
実装する場合、メッセージを受信します。load
ランタイムがload
の特殊なケースとしてメソッドを_class_getLoadMethod
検索し、objc-runtime-new.mm
から直接呼び出す方法を確認できます。call_class_loads
objc-loadmethod.mm
ランタイムはload
、同じクラスの複数のカテゴリがを実装している場合でも、ロードするすべてのカテゴリのメソッドも実行しますload
。これは珍しいことです。通常、2つのカテゴリが同じクラスで同じメソッドを定義している場合、一方のメソッドが「勝ち」て使用され、もう一方のメソッドが呼び出されることはありません。
initialize
方法_
ランタイムは、最初のメッセージ(または以外)をクラスオブジェクトまたはクラスの任意のインスタンスinitialize
に送信する直前に、クラスオブジェクトのメソッドを呼び出します。このメッセージは通常のメカニズムを使用して送信されるため、クラスがを実装していないが、実装しているクラスを継承している場合、クラスはそのスーパークラスのを使用します。ランタイムは、最初にクラスのすべてのスーパークラスにを送信します(スーパークラスがまだ送信されていない場合)。load
initialize
initialize
initialize
initialize
initialize
例:
@interface Superclass : NSObject
@end
@interface Subclass : Superclass
@end
@implementation Superclass
+ (void)initialize {
NSLog(@"in Superclass initialize; self = %@", self);
}
@end
@implementation Subclass
// ... initialize not implemented in this class
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
Subclass *object = [[Subclass alloc] init];
}
return 0;
}
このプログラムは、2行の出力を出力します。
2012-11-10 16:18:38.984 testApp[7498:c07] in Superclass initialize; self = Superclass
2012-11-10 16:18:38.987 testApp[7498:c07] in Superclass initialize; self = Subclass
システムはinitialize
メソッドを遅延送信するため、プログラムが実際にクラス(またはサブクラス、またはクラスのインスタンス)にメッセージを送信しない限り、クラスはメッセージを受信しません。そして、あなたが受け取るinitialize
までに、あなたのプロセスのすべてのクラスはすでに受け取っているはずload
です(適切な場合)。
実装する標準的な方法initialize
は次のとおりです。
@implementation Someclass
+ (void)initialize {
if (self == [Someclass class]) {
// do whatever
}
}
このパターンのポイントは、をSomeclass
実装しないサブクラスがある場合に、それ自体を再初期化しないようにすることinitialize
です。
ランタイムは、の関数でinitialize
メッセージを送信します。通常のメッセージ送信機能である送信に 使用されていることがわかります。_class_initialize
objc-initialize.mm
objc_msgSend
参考文献
このトピックに関するMikeAshの金曜日のQ&Aを確認してください。