यह उद्देश्य-सी रनटाइम के पिछले संस्करण का एक आर्टिफैक्ट है।
मूल रूप से, @synthesize
accessors तरीकों बनाने के लिए इस्तेमाल किया गया था, लेकिन क्रम अभी भी आवश्यक है कि उदाहरण चर स्पष्ट रूप से instantiated किया जा सकता था:
@interface Foo : Bar {
Baz *_qux;
}
@property (retain) Baz *qux;
@end
@implementation Foo
@synthesize qux = _qux;
- (void)dealloc {
[_qux release];
[super dealloc];
}
@end
लोग अपने उदाहरण चर उपसर्ग उन्हें उनके गुणों से अलग हैं (भले ही ऐप्पल नहीं चाहता कि आप अंडरस्कोर का उपयोग करें, लेकिन यह एक अलग मामला है)। आप आवृत्ति चर पर इंगित करने के लिए संपत्ति को संश्लेषित करते हैं। लेकिन मुद्दा यह है कि, _qux
एक आवृत्ति चर है और self.qux
(या [self qux]
) संदेश qux
संदेश self
पर भेजा गया संदेश है।
हम इंस्टेंस वैरिएबल का उपयोग सीधे -dealloc
में करते हैं; बजाय एक्सेसर पद्धति का उपयोग करके इस प्रकार दिखाई देगा (हालांकि मैं इसकी सलाह नहीं देते, कारणों के लिए मैं शीघ्र ही तरीका बताएंगे):
- (void)dealloc {
self.qux = nil; // [self setQux:nil];
[super dealloc];
}
यह qux
जारी है, साथ ही संदर्भ बाहर के शून्यीकरण का प्रभाव पड़ता है।लेकिन इसमें दुर्भाग्यपूर्ण दुष्प्रभाव हो सकते हैं:
- आप कुछ अप्रत्याशित अधिसूचनाओं को फायरिंग समाप्त कर सकते हैं। अन्य ऑब्जेक्ट
qux
में परिवर्तनों को देख रहे हैं, जिन्हें रिकॉर्ड करने के लिए एक एक्सेसर विधि का उपयोग करने पर रिकॉर्ड किया जाता है।
- (इस बिंदु पर सभी सहमत नहीं हैं :) पॉइंटर को ज़ीरोइंग करना क्योंकि एक्सेसर आपके प्रोग्राम में तर्क त्रुटियों को छुपा सकता है। यदि आप किसी ऑब्जेक्ट के बाद किसी ऑब्जेक्ट के आवृत्ति चर का उपयोग कर रहे हैं, तो ऑब्जेक्ट को हटा दिया गया है, आप कुछ गंभीरता से गलत कर रहे हैं। उद्देश्य-सी के
nil
-मेसिंग सेमेन्टिक्स के कारण, हालांकि, आप कभी भी नहीं जान पाएंगे, nil
पर सेट करने के लिए एक्सेसर का उपयोग करने के बाद। यदि आपने इंस्टेंस वैरिएबल को सीधे जारी किया था और संदर्भ को शून्य से बाहर नहीं किया था, तो हटाए गए ऑब्जेक्ट तक पहुंचने से EXC_BAD_ACCESS
जोरदार होगा।
रनटाइम के बाद के संस्करणों ने एक्सेसर विधियों के अतिरिक्त इंस्टेंस चर को संश्लेषित करने की क्षमता को जोड़ा। क्रम के इन संस्करणों के साथ, ऊपर कोड उदाहरण चर को छोड़ते हुए लिखा जा सकता है:
@interface Foo : Bar
@property (retain) Baz *qux;
@end
@implementation Foo
@synthesize qux = _qux;
- (void)dealloc {
[_qux release];
[super dealloc];
}
@end
यह वास्तव में Foo
पर एक उदाहरण चर _qux
कहा जाता है, जो मनुष्य और सेटर संदेशों -qux
और -setQux:
द्वारा पहुँचा है संश्लेषण करती।
मैं इसके खिलाफ अनुशंसा करता हूं: यह थोड़ा गन्दा है, लेकिन अंडरस्कोर का उपयोग करने का एक अच्छा कारण है; अर्थात्, गलती से सीधे ivar पहुंच के खिलाफ सुरक्षा के लिए। तब
@interface Foo : Bar
@property (retain) Baz *qux;
@end
@implementation Foo
@synthesize qux;
- (void)dealloc {
[qux release];
[super dealloc];
}
@end
, जब आप सीधे उदाहरण चर का उपयोग करना चाहते हैं, बस: आपको लगता है कि आप यदि आप एक कच्चे उदाहरण चर या एक्सेसर विधि का उपयोग कर रहे हैं कि क्या याद करने के लिए अपने आप को भरोसा कर सकते हैं, तो बस इसे इस तरह के बजाय करना qux
(जो संकेतक से किसी सदस्य तक पहुंचने के लिए सी वाक्यविन्यास में self->qux
का अनुवाद करता है)। जब आप एक्सेसर्स विधियों का उपयोग करना चाहते हैं (जो पर्यवेक्षकों को सूचित करेंगे, और अन्य रोचक चीजें करते हैं, और स्मृति प्रबंधन के संबंध में चीजों को सुरक्षित और आसान बनाते हैं), self.qux
([self qux]
) और self.qux = blah;
([self setQux:blah]
) का उपयोग करें।
दुख की बात यह है कि ऐप्पल का नमूना कोड और टेम्पलेट कोड बेकार है। उचित उद्देश्य-सी शैली के लिए इसे कभी भी गाइड के रूप में उपयोग न करें, और निश्चित रूप से इसे उचित सॉफ़्टवेयर आर्किटेक्चर के लिए मार्गदर्शिका के रूप में कभी भी उपयोग न करें। :)
'@synthesize quz = _quz लिए एक बहुत अच्छा कारण नहीं है; '; जब आप 'self.quz' और इसके विपरीत' होते हैं तो यह गलती से 'quz' लिखता है। संकलक मुद्दा अपेक्षाकृत कम रहता था, लेकिन असली। यदि आपको बोर्क किए गए उदाहरण मिलते हैं, तो कृपया बग दर्ज करें। – bbum
@bbum अच्छा बिंदु फिर अंडरस्कोर-नामकरण।मैं आमतौर पर सही चीज़ टाइप करने के लिए खुद पर भरोसा करता हूं (या कम से कम इसे ठीक करने के लिए इसे ठीक करें), लेकिन यह निश्चित रूप से कुछ है जो आपके कोडिंग-शैली को क्राफ्ट करते समय सोचता है (मैं सौंदर्यशास्त्र के पक्ष में गलती करता हूं, लेकिन यह पूरी तरह से मान्य है दुर्घटनाओं के खिलाफ सुरक्षा की ओर दुबला)। –
यदि आप हाथ से सभी बॉयलरप्लेट लिखना नहीं चाहते हैं तो आप https://github.com/holtwick/xobjc (ओपन सोर्स प्रोजेक्ट के शर्मनाक स्व प्रोमो;) का उपयोग करना चाहेंगे) यह अग्रणी और पिछला अंडरस्कोर का समर्थन करता है । पिछली बार Google स्टाइलगाइड द्वारा ओबीजेसी के लिए अनुशंसा की जाती है। यह भी उपयोगी है, क्योंकि ऐप्पल अपने कोड में अग्रणी अंडरस्कोर का भी उपयोग करता है और इसलिए आपको दुर्लभ मामलों में निजी एपीआई के साथ परेशानी हो सकती है। – Holtwick