2009-08-26 4 views
5

को कॉल करना इस छोटे से वाक्यविन्यास उद्देश्य-सी में मेरे लिए एक भ्रम का थोड़ा सा रहा है।उद्देश्य-सी: जब self.myObject को कॉल करना है तो बस myObject

जब मैं सिर्फ myObject बुला बनाम self.myObject बुलाना चाहिए?

यह अनावश्यक लगता है हालांकि वे अंतर-परिवर्तनीय नहीं हैं।

क्या कोई मुझे प्रबुद्ध करेगा?

+0

मुझे यहां एक समान पोस्ट मिली: http://stackoverflow.com/questions/1051543/should-i-use-self-keyword-properties-in-the-implementation – Jonah

उत्तर

8

आप सिर्फ उन्हें पहुँच रहे हैं, वहाँ बहुत कारण self.member उपयोग करने के लिए नहीं है। यदि आप असाइनमेंट कर रहे हैं, तो यह अच्छा है कि आप सरल @property (assign) पैरामीटर से अधिक कर रहे हैं - उदाहरण के लिए, बनाए रखें, कॉपी करें, आदि, ताकि यह आपके द्वारा लिखे गए कोड पर सहेजा जा सके। एक उदाहरण:

myObject = anotherObject; 
self.myObject = anotherObject; 

दूसरी पसंद यह सुनिश्चित करेंगे कि आप वास्तव में वस्तु जिस तरह से आप चाहते बताए रहे हैं (एक प्रति प्राप्त करने, बढ़ती है, तो संख्या को बनाए रखने आदि)। यह [self setMyObject:anotherObject] से अलग नहीं है।

के बाद से बिंदु संकेतन का संकलक द्वारा संदेश (कैसे x[5] नियमित सरणी काम में *(x + 5*sizeof(x)) हो जाता है के समान) के लिए प्रतिस्थापित किया जाता है, वहाँ कोई भूमि के ऊपर या नियमित रूप से संदेशों से अधिक बिंदु संकेतन का उपयोग करने में अतिरिक्त क्षमता है।

1

आपको लगभग उसी वर्ग के कार्यान्वयन के भीतर संपत्ति एक्सेसर्स को कभी भी कॉल नहीं करना चाहिए। कक्षा के इंस्टेंस विधियों में आंतरिक स्थिति तक सुविधाजनक पहुंच है, इसलिए आमतौर पर यह उस स्थिति तक पहुंचने के लिए समझ में आता है।

आप, संश्लेषित accesors का उपयोग कर फिर उन्हें बुला रहे हैं बस (शायद) अनावश्यक भूमि के ऊपर कहते हैं। यदि एक्सेसर्स के पास अधिक जटिल कार्यान्वयन है, तो आप कोड के उद्देश्य को अस्पष्ट कर रहे हैं।

अंत में, कुछ लोग ऑब्जेक्टिव-सी के लिए नए हैं self.property वाक्य रचना और संश्लेषित accessors का उपयोग कोको स्मृति प्रबंधन को समझने के लिए होने से बचने के लिए प्रयास करने के। आपको वास्तव में यह सीखने की ज़रूरत है कि यह कैसे काम करता है, इसलिए ऐसा करने से बचने का प्रयास काउंटर-उत्पादक है।

+0

सिर्फ इसलिए कि आप ऑब्जेक्ट की आंतरिक स्थिति के साथ खराब हो सकते हैं सभी willy-nilly का मतलब यह नहीं है कि आपको चाहिए। और सिर्फ इसलिए कि आप समझते हैं कि मेमोरी प्रबंधन कैसे काम करता है इसका मतलब यह नहीं है कि आप इसे पूरी तरह से पूरी टीम करेंगे। विधियों के समूह के बीच अपनी मेमोरी प्रबंधन ज़िम्मेदारी को डुप्लिकेट करना बग मांग रहा है। – Chuck

+0

मैं सम्मान से असहमत हूं। यदि आपके वर्गों में बहुत से @ synthesize'd एक्सेसर्स हैं, तो वे शायद खराब रूप से डिज़ाइन किए गए हैं। यदि आपने गैर-तुच्छ एक्सेसर्स लागू किए हैं, तो आप उन्हें उचित रूप से उपयोग करने के बारे में सावधान रहना चाहते हैं। संपत्ति एक्सेसर्स का उपयोग आपकी कक्षा के लिए * बाहरी * इंटरफ़ेस बनाने के लिए किया जाना है। कभी-कभी, यह आपकी कक्षा के आंतरिक रूप से बाहरी इंटरफ़ेस का उपयोग करने के लिए समझ में आता है, लेकिन अक्सर, यह अनावश्यक (या काउंटर-उत्पादक) है। –

+0

किसी भी मामले में, यदि आप वास्तव में एक्सेसर्स का उपयोग करना चाहते हैं, तो "स्वयं" का उपयोग करना चाहते हैं। सिंटैक्स बस अस्पष्ट करता है कि क्या हो रहा है, इसलिए आपको स्पष्ट संदेश का उपयोग करना चाहिए। यदि आप कोई संपत्ति सेट कर रहे हैं, तो "[self setFoo: value]" "self.foo = value" से केवल 5 वर्ण लंबा है। पढ़ने के लिए, अंतर भी कम है। आप केवल एक बार कोड लिखने जा रहे हैं, इसलिए आपको यह स्पष्ट करने की कोशिश करनी चाहिए कि क्या हो रहा है जब आप (या कोई और) इसे बाद में पढ़ता है। –

1

आप कोर डाटा का उपयोग कर रहे हैं, तो आप अनिवार्य रूप से हमेशा accessors, का उपयोग करना चाहिए के बाद से कुछ गुण लगातार की दुकान से लोड नहीं किया जा सकता है जब तक की जरूरत है। आप कोर डाटा उपयोग नहीं कर रहे हैं (यह मानते हुए कि आप एक SQLite दुकान का उपयोग कर रहे, वैसे भी।)

, तो आप आम तौर पर सिर्फ सीधे myObject उपयोग करने के लिए यदि आप रहे केवल मूल्य पढ़ने सुरक्षित हैं। यदि आप myObject के मान को संशोधित कर रहे हैं, तो आपको यह सुनिश्चित करने के लिए एक्सेसर्स का उपयोग करने की आवश्यकता है कि उस संपत्ति के मूल्य को देखकर कोई अन्य ऑब्जेक्ट उचित रूप से अधिसूचित किया गया हो। दूसरे शब्दों में:

// Not changing the value of myObject, so no accessor needed 
[someMutableArray addObject:myObject]; 

// Changes the value, so you need to use the accessor 
self.myObject = newObject;  
[self setMyObject:newObject]; // Exactly identical to the previous line. 

सामान्यतः, हालांकि, बहुत कम ओवरहेड है; मैं हमेशा एक ही वस्तु के भीतर, एक्सेसर्स का उपयोग करना पसंद करता हूं। (बेशक, उन्हें initializers में उपयोग करने पर तर्क है, लेकिन वह एक अलग मुद्दा है।)

3

मानव संसाधन विकास मंत्री मैं नहीं कह सकता कि मैं मार्क या Cinder6 से सहमत हैं।

ठीक है, मैं पहले भाग में सहमत हूं। :-) self.foo-foo विधि का आविष्कार कर रहा है। सादा foofoo ivar तक पहुंच रहा है।

ज्यादातर परिस्थितियों में आपको हमेशा अपने तरीकों से गुज़रना चाहिए।वे आपको वास्तविक भंडारण से दूर करने के लिए और किसी अन्य व्यवहार से दूर होने के लिए आवश्यक हैं जो आवश्यक हो सकता है। अगर आपने बाद में अपनी कक्षा को उप-वर्गीकृत किया तो क्या होता है इसके बारे में सोचें। अधिकांश भाग के लिए आप उन स्थानों पर अपनी सार्वजनिक विधियों को कॉल करना चाहते हैं जहां आप अपनी कार्यक्षमता तक पहुंचते हैं।

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

0

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

जब आप प्रॉपर्टी मेमोरी मैनेजमेंट व्यवहार सुनिश्चित करना चाहते हैं तो एक्सेसर्स/गुणों का उपयोग करना सबसे अच्छा है, जो कहने के लिए, हमेशा सेटर या डॉट नोटेशन का उपयोग करने के लिए ivar सेट करते समय, और आपके द्वारा अनुसरण किए जाने वाले मेमोरी प्रबंधन पैटर्न के आधार पर , ivar प्राप्त करते समय हमेशा एक्सेसर्स/गुणों का उपयोग करने के लिए।

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

- (id)foo {return [[foo retain] autorelease]; } 
- (void)setFoo:(id)aFoo { 
    if(! [aFoo isEqual:foo]) { 
    [foo release]; 
    foo = [aFoo retain]; 
    } 
} 

यह है कि पैटर्न वे अपने संश्लेषित accessors में पालन है निहित है। व्यक्तिगत रूप से, मैं सेटर में autorelease करना पसंद करते हैं:

- (id)foo {return foo;} 
- (void)setFoo:(id)aFoo { 
    [foo autorelease]; 
    foo = [aFoo retain]; 
} 

इस नए मूल्य और इसकी जगह से पहले पुराने मूल्य autoreleasees। यह गेटटर में बनाए रखने और ऑटोरेलीज़िंग के समान ही प्रभाव डालता है, लेकिन ऑब्जेक्ट को केवल एक ऑटोरेलीज पूल में जोड़ने के लिए आवश्यक है। अधिकांश समय इसमें एक की गिनती होती है और इसे स्वत: बंद नहीं किया जाता है, इसलिए यह कहीं भी नहीं होगा, इससे कोई फर्क नहीं पड़ता कि क्या होता है। अगर संपत्ति को उस कोड के दौरान प्रतिस्थापित किया गया है जो अभी भी इसे पकड़ रहा है (जैसे कि एक प्रतिनिधि कॉलबैक में), तो यह इसके अंतर्गत से गायब नहीं होगा।

इसका मतलब यह है कि एक्सेसर्स/गुणों का उपयोग करने से आपको विश्वास होगा कि आपकी ऑब्जेक्ट्स तब तक रहेंगी जब तक उन्हें कोड के किसी अन्य भाग के बिना उन्हें आपके नीचे से जारी करने की आवश्यकता न हो।

एक्सेसर्स/गुणों का हमेशा उपयोग करने का अंतिम और सबसे अच्छा कारण यह है कि यह प्रत्येक संपत्ति के लिए एक कम धारणा बनाता है: उस संपत्ति के लिए अंतर्निहित ivar है, और इसका एक ही नाम है (मुझे लगता है कि यह दो धारणाएं हैं) । शायद भविष्य में आप एक इवर को व्युत्पन्न एक्सेसर के साथ बदलना चाहेंगे। संपत्ति नोटेशन अभी भी काम करेगा। शायद आप ivar को फिर से नाम देना चाहते हैं; संपत्ति अभी भी काम करेगी। सौभाग्य से, एक्सकोड में रीफैक्टरिंग आमतौर पर भरोसा किया जा सकता है, लेकिन परेशान क्यों?

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

+0

आपके गेटर/सेटर विधियां ऐप्पल के समान नहीं हैं। आपका गेटटर मूल रूप से वह है जिसे आप "असाइन" संपत्ति के लिए उपयोग करेंगे और सेटटर "बनाए रखने" संपत्ति के लिए है। मुझे यकीन है कि यह ज्यादातर समय काम करता है लेकिन मुझे लगता है कि अगर आप अपने स्वयं के ऑटोरेलीज पूल का उपयोग शुरू करते हैं तो यह अनावश्यक हो जाएगा। कोको के बाकी हिस्सों में उपयोग किए जाने वाले सम्मेलनों के साथ रहना सर्वोत्तम है। –

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