load
wiadomość
Środowisko wykonawcze wysyła load
komunikat do każdego obiektu klasy, wkrótce po załadowaniu obiektu klasy do przestrzeni adresowej procesu. W przypadku klas, które są częścią pliku wykonywalnego programu, środowisko wykonawcze wysyła load
komunikat na bardzo wczesnym etapie życia procesu. W przypadku klas, które znajdują się we współużytkowanej (ładowanej dynamicznie) bibliotece, środowisko wykonawcze wysyła komunikat ładowania zaraz po załadowaniu biblioteki współużytkowanej do przestrzeni adresowej procesu.
Ponadto środowisko wykonawcze wysyła load
do obiektu klasy tylko wtedy, gdy ten obiekt klasy sam implementuje load
metodę. Przykład:
@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
Środowisko wykonawcze wysyła load
komunikat do Superclass
obiektu klasy. To nie nie wysyła load
wiadomość do Subclass
obiektu klasy, choć Subclass
dziedziczy metodę od Superclass
.
Środowisko wykonawcze wysyła load
komunikat do obiektu klasy po wysłaniu load
komunikatu do wszystkich obiektów nadklasy klasy (jeśli te obiekty nadklasy są zaimplementowane load
) i wszystkich obiektów klas w bibliotekach współdzielonych, do których tworzysz łącze. Ale nie wiesz jeszcze, które inne klasy w twoim własnym pliku wykonywalnym otrzymały load
.
Każda klasa, którą twój proces ładuje do swojej przestrzeni adresowej, otrzyma load
komunikat, jeśli implementuje load
metodę, niezależnie od tego, czy twój proces używa tej klasy w inny sposób.
Można zobaczyć, jak środowisko wykonawcze wyszukuje load
metodę jako szczególny przypadek w _class_getLoadMethod
od objc-runtime-new.mm
, i wzywa go bezpośrednio z call_class_loads
w objc-loadmethod.mm
.
Środowisko uruchomieniowe uruchamia również load
metodę każdej ładowanej kategorii, nawet jeśli kilka kategorii na tym samym implementacji klasy load
. To jest niezwykłe. Zwykle, jeśli dwie kategorie definiują tę samą metodę w tej samej klasie, jedna z metod „wygra” i zostanie użyta, a druga nigdy nie zostanie wywołana.
initialize
Metoda
Środowisko wykonawcze wywołuje initialize
metodę na obiekcie klasy tuż przed wysłaniem pierwszej wiadomości (innej niż load
lub initialize
) do obiektu klasy lub jakichkolwiek instancji klasy. Ta wiadomość jest wysyłana przy użyciu normalnego mechanizmu, więc jeśli twoja klasa nie implementuje initialize
, ale dziedziczy po klasie, która to robi, wtedy twoja klasa użyje swojej nadklasy initialize
. Środowisko wykonawcze wyśle najpierw initialize
do wszystkich nadklas klasy (jeśli nadklasy nie zostały jeszcze wysłane initialize
).
Przykład:
@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;
}
Ten program wypisuje dwa wiersze wyniku:
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
Ponieważ system wysyła initialize
metodę leniwie, klasa nie otrzyma komunikatu, chyba że program faktycznie wyśle komunikaty do klasy (lub podklasy albo instancji klasy lub podklas). Zanim to zrobisz initialize
, wszystkie zajęcia w Twoim procesie powinny już być load
(jeśli to konieczne).
Kanoniczny sposób implementacji initialize
jest następujący:
@implementation Someclass
+ (void)initialize {
if (self == [Someclass class]) {
// do whatever
}
}
Celem tego wzorca jest uniknięcie Someclass
ponownej inicjalizacji, gdy ma podklasę, która nie jest implementowana initialize
.
Środowisko wykonawcze wysyła initialize
komunikat w _class_initialize
funkcji w formacie objc-initialize.mm
. Możesz zobaczyć, że używa objc_msgSend
do wysłania, co jest normalną funkcją wysyłania wiadomości.
Dalsza lektura
Zobacz piątkowe pytania i odpowiedzi Mike'a Asha na ten temat.
+load
jest wysyłany oddzielnie dla kategorii; oznacza to, że każda kategoria w klasie może zawierać własną+load
metodę.