संपादित करें: यह कार्यान्वयन ARC के साथ जुड़ा हुआ है। कृपया इस पर एक नज़र डालें कि मैं एक उद्देश्य-सी सिंगलटन कैसे लागू कर सकता हूं जो एआरसी के साथ संगत है? सही कार्यान्वयन के लिए।
आरंभिक सभी कार्यान्वयन मैंने अन्य उत्तरों में पढ़ा है, एक सामान्य त्रुटि साझा करते हैं।
+ (void) initialize {
_instance = [[MySingletonClass alloc] init] // <----- Wrong!
}
+ (void) initialize {
if (self == [MySingletonClass class]){ // <----- Correct!
_instance = [[MySingletonClass alloc] init]
}
}
Apple प्रलेखन आपको अपने प्रारंभिक ब्लॉक में वर्ग प्रकार की जांच करने की सलाह देता है। क्योंकि उप-वर्ग डिफ़ॉल्ट रूप से इनिशियलाइज़ कॉल करते हैं। एक गैर-स्पष्ट मामला मौजूद है जहां उप-वर्ग केवीओ के माध्यम से अप्रत्यक्ष रूप से बनाए जा सकते हैं। यदि आप किसी अन्य कक्षा में निम्न पंक्ति जोड़ते हैं:
[[MySingletonClass getInstance] addObserver:self forKeyPath:@"foo" options:0 context:nil]
ऑब्जेक्टिव-सी का अर्थ है कि माईसिंगटनक्लास का एक उपवर्ग बनाएगा, जिसके परिणामस्वरूप दूसरा ट्रिगर होगा +initialize
।
आप सोच सकते हैं कि आपको अपने इनिट ब्लॉक में डुप्लिकेट इनिशियलाइज़ेशन की जाँच करनी चाहिए जैसे:
- (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;
}
टीएल; डीआर, यहाँ मेरा कार्यान्वयन है
@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।)