Tin loadnhắn
Thời gian chạy gửi loadthông báo đến từng đối tượng lớp, rất nhanh sau khi đối tượng lớp được tải trong không gian địa chỉ của tiến trình. Đối với các lớp là một phần của tệp thực thi của chương trình, thời gian chạy sẽ gửi loadtin nhắn rất sớm trong vòng đời của quy trình. Đối với các lớp trong thư viện dùng chung (được tải động), bộ thực thi sẽ gửi thông báo tải ngay sau khi thư viện dùng chung được tải vào không gian địa chỉ của tiến trình.
Hơn nữa, thời gian chạy chỉ gửi loadđến một đối tượng lớp nếu chính đối tượng lớp đó thực hiện loadphương thức. Thí dụ:
@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
Thời gian chạy gửi loadtin nhắn đến Superclassđối tượng lớp. Nó không gửi loadtin nhắn đến Subclassđối tượng lớp, mặc dù Subclasskế thừa phương thức từ đó Superclass.
Thời gian chạy gửi loadtin nhắn đến một đối tượng lớp sau khi nó đã gửi loadtin nhắn đến tất cả các đối tượng siêu lớp của lớp đó (nếu các đối tượng siêu lớp đó thực hiện load) và tất cả các đối tượng lớp trong các thư viện chia sẻ mà bạn liên kết đến. Nhưng bạn không biết những lớp khác trong chương trình thực thi của riêng bạn đã nhận loadđược.
Mỗi lớp mà tiến trình của bạn tải vào không gian địa chỉ của nó sẽ nhận được một loadthông báo, nếu nó thực hiện loadphương thức đó, bất kể quá trình của bạn có sử dụng lớp nào khác không.
Bạn có thể xem như thế nào thời gian chạy ngước lên các loadphương pháp như một trường hợp đặc biệt trong _class_getLoadMethodcác objc-runtime-new.mm, và gọi đó là trực tiếp từ call_class_loadstrong objc-loadmethod.mm.
Thời gian chạy cũng chạy loadphương thức của mọi danh mục mà nó tải, ngay cả khi một số danh mục trên cùng một lớp thực hiện load. Điều này là bất thường. Thông thường, nếu hai danh mục định nghĩa cùng một phương thức trên cùng một lớp, một trong các phương thức đó sẽ giành chiến thắng và được sử dụng, và phương thức kia sẽ không bao giờ được gọi.
các initializePhương pháp
Thời gian chạy gọi initializephương thức trên một đối tượng lớp ngay trước khi gửi tin nhắn đầu tiên (ngoài loadhoặc initialize) đến đối tượng lớp hoặc bất kỳ trường hợp nào của lớp. Thông báo này được gửi bằng cơ chế bình thường, vì vậy nếu lớp của bạn không thực hiện initialize, nhưng kế thừa từ một lớp có, thì lớp của bạn sẽ sử dụng lớp của nó initialize. Thời gian chạy sẽ gửi initializecho tất cả các siêu lớp của lớp trước (nếu các siêu lớp chưa được gửi initialize).
Thí dụ:
@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;
}
Chương trình này in hai dòng đầu ra:
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
Vì hệ thống gửi initializephương thức một cách lười biếng, một lớp sẽ không nhận được thông báo trừ khi chương trình của bạn thực sự gửi tin nhắn đến lớp (hoặc một lớp con hoặc các thể hiện của lớp hoặc các lớp con). Và vào thời điểm bạn nhận được initialize, mọi lớp trong quy trình của bạn đã nhận được load(nếu phù hợp).
Cách thức kinh điển để thực hiện initializelà:
@implementation Someclass
+ (void)initialize {
if (self == [Someclass class]) {
// do whatever
}
}
Điểm của mẫu này là để tránh Someclasstự khởi tạo lại khi nó có một lớp con không thực hiện initialize.
Thời gian chạy gửi initializetin nhắn trong _class_initializehàm trong objc-initialize.mm. Bạn có thể thấy rằng nó sử dụng objc_msgSendđể gửi nó, đó là chức năng gửi tin nhắn bình thường.
đọc thêm
Kiểm tra câu hỏi thứ sáu của Mike Ash về chủ đề này.
+loadđược gửi riêng cho các danh mục; nghĩa là, mọi thể loại trên một lớp có thể chứa+loadphương thức riêng của nó .