Tin load
nhắn
Thời gian chạy gửi load
thô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 load
tin 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 load
phươ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 load
tin nhắn đến Superclass
đối tượng lớp. Nó không gửi load
tin nhắn đến Subclass
đối tượng lớp, mặc dù Subclass
kế thừa phương thức từ đó Superclass
.
Thời gian chạy gửi load
tin nhắn đến một đối tượng lớp sau khi nó đã gửi load
tin 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 load
thông báo, nếu nó thực hiện load
phươ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 load
phương pháp như một trường hợp đặc biệt trong _class_getLoadMethod
các objc-runtime-new.mm
, và gọi đó là trực tiếp từ call_class_loads
trong objc-loadmethod.mm
.
Thời gian chạy cũng chạy load
phươ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 initialize
Phương pháp
Thời gian chạy gọi initialize
phươ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 load
hoặ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 initialize
cho 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 initialize
phươ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 initialize
là:
@implementation Someclass
+ (void)initialize {
if (self == [Someclass class]) {
// do whatever
}
}
Điểm của mẫu này là để tránh Someclass
tự 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 initialize
tin nhắn trong _class_initialize
hà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+load
phương thức riêng của nó .