แก้ไข: การใช้งานนี้ล้าสมัยกับ ARC โปรดดูที่ฉันจะใช้ Objective-C singleton ที่เข้ากันได้กับ ARC ได้อย่างไร สำหรับการใช้งานที่ถูกต้อง
การใช้งานทั้งหมดของการเริ่มต้นฉันได้อ่านในคำตอบอื่น ๆ แบ่งปันข้อผิดพลาดทั่วไป
+ (void) initialize {
_instance = [[MySingletonClass alloc] init] // <----- Wrong!
}
+ (void) initialize {
if (self == [MySingletonClass class]){ // <----- Correct!
_instance = [[MySingletonClass alloc] init]
}
}
เอกสารประกอบของ Apple แนะนำให้คุณตรวจสอบประเภทของชั้นเรียนในบล็อกเริ่มต้นของคุณ เพราะคลาสย่อยเรียกการเริ่มต้นตามค่าเริ่มต้น มีกรณีที่ไม่ชัดเจนซึ่งอาจสร้างคลาสย่อยทางอ้อมผ่าน KVO สำหรับถ้าคุณเพิ่มบรรทัดต่อไปนี้ในคลาสอื่น:
[[MySingletonClass getInstance] addObserver:self forKeyPath:@"foo" options:0 context:nil]
Objective-C โดยปริยายจะสร้าง subclass ของ MySingletonClass +initialize
ผลในสองเรียกของ
คุณอาจคิดว่าคุณควรตรวจสอบการกำหนดค่าเริ่มต้นซ้ำในบล็อก init ของคุณโดยปริยายเช่น:
- (id) init { <----- Wrong!
if (_instance != nil) {
// Some hack
}
else {
// Do stuff
}
return self;
}
แต่คุณจะยิงตัวเองในเท้า; หรือแย่กว่านั้นคือให้โอกาสผู้พัฒนารายอื่นยิงตัวเองด้วยการเดินเท้า
- (id) init { <----- Correct!
NSAssert(_instance == nil, @"Duplication initialization of singleton");
self = [super init];
if (self){
// Do stuff
}
return self;
}
TL; DR นี่คือการดำเนินการของฉัน
@implementation MySingletonClass
static MySingletonClass * _instance;
+ (void) initialize {
if (self == [MySingletonClass class]){
_instance = [[MySingletonClass alloc] init];
}
}
- (id) init {
ZAssert (_instance == nil, @"Duplication initialization of singleton");
self = [super init];
if (self) {
// Initialization
}
return self;
}
+ (id) getInstance {
return _instance;
}
@end
(แทนที่ ZAssert ด้วยมาโครการยืนยันของเราเองหรือเพียงแค่ NSAssert)