2012-05-03 17 views
5

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

उत्तर

13

आप उदाहरण चर पूरी तरह

नहीं बनाने बंद कर सकते हैं, तो आप (एक अर्थ में) नहीं कर सकता। यदि आप गुण रखते हैं तो आप उन्हें क्या रोक सकते हैं। यदि आप किसी संपत्ति को संश्लेषित करते हैं और आपने इंस्टवर घोषित नहीं किया है, तो यह आपके लिए घोषित किया जाएगा, इसलिए आप एक उदाहरण चर बना रहे हैं, बस स्पष्ट रूप से नहीं।

क्या वे अभी भी ऐसे उद्देश्य की सेवा करते हैं जहां गुण अनुचित होंगे?

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

एआरसी को अपनाने का एक अच्छा कारण है: गुण केवल कक्षा के एपीआई का हिस्सा होने के अपने वास्तविक उद्देश्य पर वापस आते हैं और स्मृति प्रबंधन कार्य को छिपाने के लिए उन्हें हैकी तरीके के रूप में उपयोग करने के लिए अब आवश्यक नहीं है।

संपादित

एक और बात: आप अब @implementation में उदाहरण चर घोषणा कर सकते हैं तो वहाँ अब @interface में किसी भी कार्यान्वयन विवरण लीक करने के लिए कोई जरूरत नहीं है। अर्थात

@implementation MyClass 
{ 
    NSString* myString; 
} 
// method definitions 
@end 

और मैं बहुत यकीन है कि यह श्रेणियों में भी काम करता है हूँ। - नीचे टिप्पणी देखें

+3

आप श्रेणियों में ivars और गुणों को जोड़ नहीं सकते हैं, क्योंकि objc-runtime केवल कक्षा-पंजीकरण के दौरान ivars जोड़ने की अनुमति देता है। रनटाइम के साथ पंजीकृत होने के बाद आप कक्षा के मेमोरी-लेआउट को बदल नहीं सकते हैं। –

+0

आप * कर सकते हैं, हालांकि कक्षाओं के विस्तार के लिए ivars जोड़ सकते हैं (निकट से संबंधित, लेकिन एक श्रेणी से अलग) – Sean

+1

@ जोनाथन सिचॉन: इसके लिए धन्यवाद, बस कोशिश की और यह पता चला कि आप उदाहरण चर के बारे में सही हैं लेकिन गुणों के बारे में गलत हैं । आप गुण जोड़ सकते हैं लेकिन आप उन्हें 'संश्लेषित' नहीं कर सकते हैं। – JeremyP

0

इस सवाल से पहले here

संबोधित जब आप synthesize उदाहरण चर नियंत्रित किया जाता है का उपयोग करें और आप के लिए instantiated किया गया था। यदि आप एक्सकोड के नए संस्करण के साथ शेर का उपयोग कर रहे हैं तो एआरसी in Transitioning to ARC

+1

मुझे नहीं लगता कि यह वही प्रश्न है, लेकिन मैंने आशा व्यक्त की है कि मैं इसे और अधिक स्पष्ट कर दूं। – Besi

0

में विभिन्न गुणों पर भी नज़र डालें, आप हमेशा बाहर से संपत्तियों तक पहुंच सकते हैं। तो यदि आप एक वर्ग के अंदर से केवल एक चर को पढ़ना चाहते हैं तो आपको अभी भी एक iVar घोषित करना होगा। object->ivar के साथ एक सार्वजनिक आईवर तक पहुंचने के लिए विधि-कॉल का उपयोग करने से थोड़ा तेज है।

+2

यह सच नहीं है। क्या होगा यदि आपने .m फ़ाइल में संपत्ति घोषित की है? – Martin

+0

आप सही ढंग से संपत्ति को छुपा सकते हैं, लेकिन आप इसे अपनी एम-फाइल के बाहर से नहीं एक्सेस कर सकते हैं, उदाहरण के लिए एक उप-वर्ग। –

+1

@ मार्टिन: चूंकि संपत्ति को विधियों की एक जोड़ी के रूप में कार्यान्वित किया जाता है, यह हमेशा रन टाइम पर उपलब्ध होता है चाहे वह कहां घोषित किया गया हो। – JeremyP

9

मैं सबकुछ संपत्तियों के रूप में घोषित करने और मैन्युअल इवरों से पूरी तरह से बचने की सलाह देता हूं। मैन्युअल रूप से इवर बनाने के लिए कोई वास्तविक उलझन नहीं है। अपने शीर्षलेख @interface में सार्वजनिक गुणों की घोषणा करें, अपनी .m फ़ाइल में एक निजी श्रेणी एक्सटेंशन में निजी गुण घोषित करें।

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

यदि आपको किसी कारण से पूरी तरह से ivar घोषित करना होगा, तो आपको इसे @implementation ब्लॉक में जेरेमीपी नोट्स के रूप में करना चाहिए।


अद्यतन (अक्टूबर-2013):

Apple's guidance (ऑब्जेक्टिव-सी के साथ प्रोग्रामिंग से: encapsulating डाटा):

अधिकांश गुण उदाहरण चर के समर्थन से कर रहे हैं

आम तौर पर, आपको संपत्ति एक्सेस के लिए एक्सेसर विधियों या डॉट सिंटैक्स का उपयोग करना चाहिए, भले ही आप किसी ऑब्जेक्ट के गुणों को इसके भीतर से एक्सेस कर रहे हों खुद कार्यान्वयन, जिस स्थिति में आप self उपयोग करना चाहिए:

...

इस नियम के अपवाद जब, आरंभीकरण, आवंटन रद्द करने या कस्टम एक्सेसर तरीकों लेखन के रूप में इस खंड में बाद में वर्णित है।

+0

केवीओ केवल कुछ आंतरिक के लिए महत्वपूर्ण नहीं है। न तो subclassing है। कक्षा के कार्यान्वयन का हिस्सा कुछ भी नहीं है, यहां तक ​​कि उप-वर्गों तक भी बाहर निकलना चाहिए। यह अच्छा ओओपी का प्रतीक है। – JeremyP

+0

केवीओ के बावजूद (हालांकि स्वयं-अवलोकन कभी-कभी उपयोग किया जाता है), क्योंकि आपको अक्सर निजी संपत्तियों (आलसी तत्कालता, थ्रेड-सुरक्षा इत्यादि) पर एक्सेसर्स की आवश्यकता होती है, और उनका उपयोग करना सरल और सस्ता है, आपको हमेशा उनका उपयोग करना चाहिए, सिवाय इसके कि जब वहां होता है एक मजबूत कारण नहीं है (यानी dealloc)। कभी-कभी इवर का उपयोग करना और कभी-कभी एक्सेसर्स का उपयोग करना त्रुटि-प्रवण होता है और शुद्धता के लिए ऑडिट करना मुश्किल होता है। –

+0

उदाहरण के बिना आप आलसी तत्काल कैसे करते हैं? मैं दोहरा दूंगा: ऐप्पल सूची पर रिपोर्ट की गई आधिकारिक रेखा आंतरिक स्थिति के लिए आवृत्ति चर का उपयोग करना है जब आपके पास एआरसी है लेकिन यदि आप पारंपरिक संदर्भ गिनती का उपयोग कर रहे हैं तो सबकुछ के लिए गुणों का उपयोग करना है। – JeremyP

संबंधित मुद्दे