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
ข้อความไปยังอ็อบเจ็กต์ superclass ของคลาสทั้งหมด (หากอ็อบเจ็กต์ superclass เหล่านั้นใช้งานload
) และอ็อบเจ็กต์คลาสทั้งหมดในไลบรารีแบบแบ่งใช้ที่คุณเชื่อมโยง แต่คุณไม่รู้ว่าคลาสอื่น ๆ ในไฟล์ปฏิบัติการของคุณได้รับแล้วหรือload
ยัง
ทุกคลาสที่กระบวนการของคุณโหลดลงในพื้นที่แอดเดรสจะได้รับload
ข้อความหากใช้load
เมธอดไม่ว่ากระบวนการของคุณจะใช้คลาสอื่นหรือไม่ก็ตาม
คุณสามารถดูวิธีรันไทม์ที่มีลักษณะขึ้นload
วิธีการเป็นกรณีพิเศษใน_class_getLoadMethod
การobjc-runtime-new.mm
และเรียกมันว่าโดยตรงจากในcall_class_loads
objc-loadmethod.mm
รันไทม์ยังเรียกใช้load
เมธอดของทุกหมวดหมู่ที่โหลดแม้ว่าจะมีหลายประเภทในคลาสเดียวกันload
ก็ตาม นี่เป็นเรื่องผิดปกติ โดยปกติถ้าสองประเภทกำหนดวิธีการเดียวกันในคลาสเดียวกันวิธีใดวิธีหนึ่งจะ“ ชนะ” และถูกนำไปใช้และอีกวิธีหนึ่งจะไม่ถูกเรียก
initialize
วิธี
รันไทม์เรียกใช้initialize
เมธอดบนคลาสอ็อบเจ็กต์ก่อนที่จะส่งข้อความแรก (นอกเหนือจากload
หรือinitialize
) ไปยังคลาสอ็อบเจ็กต์หรืออินสแตนซ์ใด ๆ ของคลาส ข้อความนี้ถูกส่งโดยใช้กลไกปกติดังนั้นหากระดับของคุณไม่ใช้initialize
แต่สืบทอดจากคลาสที่ไม่แล้วระดับของคุณจะใช้ของ initialize
superclass รันไทม์จะส่งinitialize
superclasses ของคลาสทั้งหมดก่อน (ถ้ายังไม่ได้ส่ง superclasses 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
ในการส่งซึ่งเป็นฟังก์ชันการส่งข้อความตามปกติ
อ่านเพิ่มเติม
ดูคำถามและคำตอบในวันศุกร์ของ Mike Ashในหัวข้อนี้
+load
มีการส่งแยกต่างหากสำหรับหมวดหมู่ นั่นคือทุกหมวดหมู่ในคลาสอาจมี+load
วิธีการของตัวเอง