Сообщение 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
_ 21_ и вызывает его прямо из call_class_loads
в _ 23_.
Среда выполнения также запускает метод load
для каждой загружаемой категории, даже если несколько категорий в одном классе реализуют load
. Это необычно. Обычно, если две категории определяют один и тот же метод для одного и того же класса, один из методов «выиграет» и будет использован, а другой метод никогда не будет вызван.
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;
}
Эта программа выводит две строки вывода:
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
для его отправки, что является обычной функцией отправки сообщений.
дальнейшее чтение
Посетите Майк Пятничные вопросы и ответы Эша по этой теме.
person
rob mayoff
schedule
10.11.2012