objective c - प्रत्येक ivar एक संपत्ति होना चाहिए?




objective-c ios (3)

जबकि डैनियल का जवाब सही है, मुझे लगता है कि यह एक महत्वपूर्ण बिंदु याद करता है। अर्थात्:

मुझे लगता है कि सादे पुराने इवर्स के बजाय गुणों का उपयोग करना बहुत अधिक कोड लेता है और यदि आप स्मृति प्रबंधन के साथ सहज हैं तो मुझे वास्तव में लाभ दिखाई नहीं देते हैं।

लाभ स्थिरता हैं; लगातार स्मृति प्रबंधन और लगातार व्यवहार।

विशेष रूप से, कोड की इन दो पंक्तियों में वास्तव में रनटाइम पर बेहद अलग व्यवहार हो सकता है:

iVar = [foo retain];
self.iVar = foo;

पहला इंस्टेंस वैरिएबल की सीधी सेटिंग है और इसमें कोई बदलाव अधिसूचना नहीं होगी। दूसरा सेटटर के माध्यम से जाता है और इस प्रकार, सेट पर किसी भी उप-वर्ग अनुकूलन को संरक्षित करता है और यह सुनिश्चित करता है कि संपत्ति के किसी भी पर्यवेक्षक को परिवर्तन की अधिसूचना दी जाती है

यदि आप सीधे अपने कोड के दौरान ivars का उपयोग कर रहे हैं (आंतरिक रूप से कक्षा में - यदि आप सीधे उस उदाहरण के बाहर से किसी उदाहरण के इवर का उपयोग कर रहे हैं, तो ... आपके कोडबेस पर काम करने वाले किसी भी ठेकेदार को अपनी दरें दोगुनी करनी चाहिए;), तो आपको अवश्य ही या तो परिवर्तन अधिसूचना प्रसार को मैन्युअल रूप से संभालते हैं (आमतौर पर willChangeValueForKey: / didChangeValueForKey को कॉल willChangeValueForKey: ) या स्पष्ट रूप से कुंजी-मूल्य निरीक्षण पर भरोसा करने वाले तंत्र के उपयोग से बचने के लिए अपने एप्लिकेशन को इंजीनियर didChangeValueForKey

आप कहते हैं "बहुत अधिक कोड लेता है"। मुझे वह नहीं दिख रहा है; कोड की उपरोक्त दो पंक्तियों में, डॉट सिंटैक्स कम वर्ण हैं। यहां तक ​​कि परंपरागत वाक्यविन्यास का उपयोग कर सेटर विधि को कॉल करना भी कम कोड होगा।

और स्मृति प्रबंधन को केंद्रीकृत करने में मूल्य को कम न करें; कॉल साइटों और दुर्घटनाग्रस्त शहर के असंख्य में एक आकस्मिक चूक।

मुझे लगता है कि आईओएस के लिए कोडिंग करते समय यह सभी जगहों पर अनुशंसा की जाती है कि गुणों को आवृत्ति चरों तक पहुंचने के लिए उपयोग किया जाना चाहिए क्योंकि यह अन्य चीजों के साथ स्मृति प्रबंधन को लाभ देता है।

यह सलाह मेरे साथ बहुत अच्छी तरह से नहीं बैठती है। मुझे लगता है कि सादे पुराने इवर्स के बजाय गुणों का उपयोग करना बहुत अधिक कोड लेता है और यदि आप स्मृति प्रबंधन के साथ सहज हैं तो मुझे वास्तव में लाभ दिखाई नहीं देते हैं। क्या यह वास्तव में महत्वपूर्ण है? इंस्टेंस चर के प्रबंधन के लिए आपका दृष्टिकोण क्या है?


निजी क्षेत्रों के लिए - मेरा सुझाव है कि केवल आदिम प्रकारों (बूल / इंट / फ्लोट इत्यादि) के लिए प्रत्यक्ष आइवर का उपयोग करना सुरक्षित है। मुझे गुणों में मेमोरी-प्रबंधन से संबंधित सबकुछ लपेटने का एक अच्छा अभ्यास मिलता है - यहां तक ​​कि शायद ही कभी इस्तेमाल किए जाने वाले फ़ील्ड। इस दृष्टिकोण का अतिरिक्त बोनस यह है कि आईडीई आमतौर पर प्रत्यक्ष आईवरों को अलग-अलग एक्सेस करता है, इसलिए आपके पास हमेशा सरल स्केलर फ़ील्ड और ऑब्जेक्ट-प्रकार फ़ील्ड का अच्छा अलगाव होता है।

इसके विपरीत मैं वर्ग सार्वजनिक इंटरफ़ेस में किसी भी प्रत्यक्ष ivars को दृढ़ता से हतोत्साहित करता हूं। भाषा की गतिशील प्रकृति के कारण यह रनटाइम त्रुटियों का कारण बन सकता है जो खोजने, स्थानीयकरण और ठीक करने के लिए बेहद मुश्किल हैं। निम्नलिखित पदानुक्रम पर विचार करें

@interface BaseControl
...
@end

@interface Label : BaseControl
...
@end

@interface Button : BaseControl {
  @public
    BOOL enabled;
}
@end

और एक कोड स्निपेट

- (void)enableAllButtons {
    NSArray *buttons = [self getAllButtons];   // expected to contain only Button instances
    for (Button *button in buttons) {
        button->enabled = YES;
    }
} 

अब कल्पना करें कि -getAllButtons तर्क में कहीं भी एक त्रुटि है और आपको उस लेबल में कुछ लेबल वापस लौटाए गए हैं - इसलिए उन लेबल क्लास उदाहरणों को ivar असाइन किया जाएगा। तथ्य यह है कि आश्चर्य की बात यह हो सकती है कि -एनेबल ऑलबूटन उस मामले में दुर्घटनाग्रस्त नहीं होंगे। लेकिन उस बिंदु पर उन लेबल उदाहरणों से आंतरिक संरचना दूषित हो जाती है और इससे अन्यथा उपयोग किए जाने पर अपरिभाषित व्यवहार और क्रैश हो जाएंगे

मेमोरी मैनेजमेंट (और सामान्य रूप से - लटकते पॉइंटर्स के साथ) के साथ कुछ लोकप्रिय समस्याओं की तरह - इस तरह की समस्याओं को ढूंढना और स्थानीयकरण करना मुश्किल है - क्योंकि त्रुटि की उपस्थिति आमतौर पर दूर होती है (समय, कोड या ऐप प्रवाह के मामले में) जगह, त्रुटि का कारण बनता है। लेकिन उस विशेष समस्या के साथ आपके पास स्थानीयकरण और इसे ठीक करने में सहायता के लिए आसान उपकरण (जैसे रिसाव / ज़ोंबी विश्लेषक इत्यादि) भी नहीं हैं - यहां तक ​​कि जब आप इसे पुन: उत्पन्न करने के तरीके सीखते हैं और आसानी से गलत स्थिति की जांच कर सकते हैं।

जाहिर है अगर आप @property (assign) BOOL enabled; आपको -एनेबल ऑलबटन में रनटाइम अपवाद का निदान करने और ठीक करने के लिए आसान मिलेगा।


सभी आइवरों के लिए संपत्ति घोषित करना वास्तव में जरूरी नहीं है। कुछ बिंदुओं को ध्यान में आता है:

  • यदि किसी इवर को ऑब्जेक्ट के जीवनकाल के दौरान केवल एक बार सौंपा जा रहा है, तो आपको संपत्ति घोषित करके वास्तव में कुछ भी हासिल नहीं होता है। केवल init दौरान / प्रतिलिपि / असाइन करें और फिर dealloc दौरान आवश्यक के रूप में जारी करें।
  • यदि एक ivar अक्सर बदला जा रहा है, एक संपत्ति घोषित करना और हमेशा एक्सेसर्स का उपयोग करना स्मृति प्रबंधन त्रुटियों से बचने के लिए आसान बना देगा।
  • गुण और ivars निजी होने के लिए हैं, तो आप .h फ़ाइल के बजाय .m फ़ाइल में क्लास एक्सटेंशन में गुण घोषित कर सकते हैं।
  • आईओएस 4.0+ को लक्षित करते समय, यदि आप किसी संपत्ति को परिभाषित करते हैं और एक्सेसर्स को संश्लेषित करते हैं तो आपको अपने शीर्षलेख में इवर घोषित करने की आवश्यकता नहीं है।

तो मैं आम तौर पर गुणों का उपयोग करता हूं, लेकिन NSMutableArray जैसे चीजों के लिए जो ऑब्जेक्ट आवंटित करता है और init का एक समूह पकड़ने के लिए उपयोग करता है, मैं एक सादे पुराने इवर का उपयोग करूंगा क्योंकि मैं कभी भी इवर को फिर से सौंप नहीं पाऊंगा।





instance-variables