संपादित
मैं शीर्ष पर इस शामिल कर रहा हूँ, तुम मेरे ऐतिहासिक मूल प्रश्न और कार्यान्वयन देख सकते हैं नीचे।हालांकि मुझे लगता है मैं कोई ताला भूमि के ऊपर के साथ एक sharedInstance विधि प्रदान करने के लिए इष्टतम रास्ता मिल गया लगता है, मैं इस बारे में संभावित चिंताओं को सुनने के लिए प्यार होता है:
// Volatile to make sure we are not foiled by CPU caches
static volatile ALBackendRequestManager *sharedInstance;
// There's no need to call this directly, as method swizzling in sharedInstance
// means this will get called after the singleton is initialized.
+ (MySingleton *)simpleSharedInstance
{
return (MySingleton *)sharedInstance;
}
+ (MySingleton*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[MySingleton alloc] init];
// Replace expensive thread-safe method
// with the simpler one that just returns the allocated instance.
SEL orig = @selector(sharedInstance);
SEL new = @selector(simpleSharedInstance);
Method origMethod = class_getClassMethod(self, orig);
Method newMethod = class_getClassMethod(self, new);
method_exchangeImplementations(origMethod, newMethod);
}
}
return (MySingleton *)sharedInstance;
}
और चारों ओर ऐतिहासिक चर्चा प्रारंभ:
मैं लॉक के बाहर उदाहरण के लिए चेक को छोड़कर, मूल कोड वास्तव में मेरे (नीचे) की तरह था।
हालांकि नई + (शून्य) प्रारंभिक विधि दिलचस्प है, मुझे यकीन नहीं है कि मुझे यह बेहतर पसंद है। ऐसा लगता है कि अब एक सिंगलटन उदाहरण प्राप्त करने के लिए आपको हमेशा कॉल करना होगा:
MySingleton instance = [[MySingleton alloc] init];
क्या यह सही नहीं है? यह अजीब लगता है, और क्या यह अधिक कुशल है यदि प्रारंभ करने के लिए कॉल पहले से ही आपके लिए बंद कर दिया गया है? डबल-लॉक विधि इस उपयोग के मामले के लिए ठीक काम करती प्रतीत होती है, जबकि लॉकिंग से बचने के लिए (डबल आवंटन की संभावित लागत पर मुझे लगता है क्योंकि एक से अधिक थ्रेड अगर के माध्यम से गिर सकता है)।
दूसरी बात जो अजीब लगती है, अगर प्रारंभिक विधि वास्तव में पसंद की जाती है तो हम इसे कहीं और क्यों नहीं देखते हैं? उद्देश्य-सी काफी समय से रहा है और मैं मौलिक तंत्र से सावधान हूं जो कि सभी प्रकाशित उदाहरणों से अलग है।
मेरे कोड मैं वर्तमान में (जो दर्पण है कि मैं कहीं और देखा है, this जवाब सहित) का उपयोग करें:
+ (MySingleton *)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [super allocWithZone:zone];
return sharedInstance; // assignment and return on first allocation
}
}
return nil; // on subsequent allocation attempts return nil
}
कृपया अपने प्रश्न को ऐसे तरीके से संपादित न करें जो मौजूदा उत्तरों को अमान्य बनाता है या अब प्रासंगिक नहीं है। – dreamlax
क्यों एक और उद्देश्य-सी सिंगलटन धागा? उदाहरण के लिए http://stackoverflow.com/questions/145154 देखें। – zoul
क्या आप गैलाघर का उपयोग नहीं करेंगे .. http://proocsithlove.com/projects/SynthesizeSingleton.h.zip http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html से। ..? अपरिवर्तनीयता और ज्वालामुखी के लिए – Fattie