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