2011-11-16 10 views
8

संभव डुप्लिकेट:
How does an underscore in front of a variable in a cocoa objective-c class work?(उद्देश्य सी) @synthesize myvar = _myvar (अगर कोई है) करने का क्या फायदा है?

यह मेरे, तुम क्यों जब तुम एक अंडरस्कोर उपसर्ग के साथ एक आंतरिक चर बनाने करना चाहते हैं (कोड की पठनीयता के लिए छोड़कर) के लिए पूरी तरह से स्पष्ट नहीं है संपत्ति बनाओ।

चूंकि सब कुछ आंतरिक रूप से संभाला जाता है, इसलिए ऐसा करने के लिए परेशान क्यों है, क्योंकि हम गेटर और सेटर में कोई कोड नहीं जोड़ते हैं?

और यहां तक ​​कि अगर मुझे गेटर या सेटर में कुछ कोड जोड़ना है, तो मुझे नहीं पता कि मैं _myvar की जांच करने के बजाय केवल Myvar पर चेक क्यों नहीं कर सकता और फिर इसे myvar को असाइन कर सकता हूं।

क्या कोई मुझे कुछ स्पष्टीकरण दे सकता है, "ऐसा करें क्योंकि हर कोई ऐसा करता है?" मैं इस अभ्यास के पीछे पूरे कारण को समझना चाहता हूं (ऐसा लगता है कि गेटटर और सेटर के लिए कोई कस्टम कोड नहीं है)।

धन्यवाद!

+1

कई, कई हैं इस प्रश्न के डुप्लिकेट: [1] (http://stackoverflow.com/questions/3521254/) [2] (http://stackoverflow.com/questions/822487/) [3] (http://stackoverflow.com/प्रश्न/237148 9) [4] (http://stackoverflow.com/questions/5582448/) [5] (http://stackoverflow.com/questions/837559/) [6] (http://stackoverflow.com/प्रश्न/6064283 /) [और अधिक ...] (http://stackoverflow.com/search?q=objc+property+underscore) –

उत्तर

8

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

संपत्ति के आवृत्ति चर से अलग नाम हो सकता है।

उदाहरण के लिए, आपके पास नाम की एक संपत्ति के साथ x नामक एक आवृत्ति चर हो सकता है। अंडरस्कोर के बारे में अब

@synthesize y = x; 

:

आप का उपयोग x चर को y संपत्ति संश्लेषण कर सकते हैं।

इंस्टेंस वैरिएबल के लिए एक अंडरस्कोर उपसर्ग का उपयोग करने के लिए, उदाहरण के चर के लिए अंडरस्कोर उपसर्ग का उपयोग करना, या उदाहरण के लिए एक ही नाम के साथ एक विधि तर्क के साथ एक विधि तर्क होने पर, यह एक सामान्य अभ्यास है।

अंडरस्कोर उपसर्ग यह भी स्पष्ट करता है कि आप एक आवृत्ति चर का जिक्र कर रहे हैं।

उदाहरण चर के लिए अंडरस्कोर उपसर्ग का उपयोग करके आप विधि के तर्कों में अंडरस्कोर बिना नाम का उपयोग करने, ढेर चर के लिए स्वतंत्र हैं, आदि

लेकिन जब एक संपत्ति का उपयोग कर, आप आमतौर पर नहीं चाहिए अंडरस्कोर लिखने के लिए उपयोगकर्ता।

तो आपके पास आमतौर पर इंस्टेंस चर के लिए x संपत्ति है।

यही कारण है कि आप लिखते हैं:

@synthesize x = _x; 

के एक उदाहरण लेते हैं:

@interface Test: NSObject 
{ 
    int x; 
} 

@property(readonly) int x; 

@end 

यह काफी आम है ...लेकिन अब कार्यान्वयन में इसकी कल्पना करें:

- (id)initWithX: (int)x 
{} 

हम नामकरण टकराव कर रहे हैं।

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

आपके कंपाइलर की चेतावनी झंडे के आधार पर, यह एक चेतावनी भी उत्पन्न कर सकता है (-Wshadow)।

आप अपने उदाहरण चर के लिए एक अंडरस्कोर उपसर्ग का उपयोग करते हैं, तो सब कुछ आसान है:

- (id)initWithX: (int)x 
{ 
    if((self = [ super init ])) 
    { 
     _x = x; 
    } 

    return self; 
} 

कोई विवाद होता है तो कोई नामकरण टक्कर, पढ़ रहे हैं ... बस एक अच्छा तरीका ... सुधार

+0

बहुत बढ़िया, धन्यवाद !!!!! यही कारण था कि मैं खोज रहा था, वास्तव में कई मामलों में महत्वपूर्ण है। – user1006198

+0

आपका स्वागत है! :) यह भी ध्यान रखें कि ऐप्पल विधियों के लिए ओबीजेसी कोडिंग दिशानिर्देशों में अंडरस्कोर उपसर्ग के उपयोग को रोकता है। यह आवृत्ति चर पर लागू नहीं होता है। – Macmade

+0

मुझे लगता है कि सी/सी ++/जावा या किसी अन्य भाषा की पृष्ठभूमि से किसी के लिए किसी संपत्ति और एक आवृत्ति चर के बीच का अंतर पता नहीं है।हां, हम सभी जानते हैं कि आवृत्ति चर क्या है, लेकिन ओसी दोस्तों को छोड़कर शब्द ** संपत्ति ** परिचित प्रतीत नहीं होता है :)। –

9

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

self.myvar = @"blah"; और _myvar = @"blah";

बनाम

self.myvar = @"blah"; और myvar = @"blah";

यह दुर्घटना से self. बाहर छोड़ने के लिए आसान है ... यह दुर्घटना से में _ डाल करने के लिए एक बहुत कठिन है।

+0

बहुत अच्छी तरह से केनी डाल दिया; मैंने नहीं सोचा था कि आपके पास गेटर और सेटर क्यों है Ivar को सीधे एक्सेस करने से बचने के लिए :) – user1006198

1

जब स्वयं की संपत्ति का उपयोग कर, यह "स्व" भूल करना आसान है:

[self.field doSomething]; // what you probably want 
[self setField:someObject]; // also kosher 
self.field = someObject; // ditto, although not my style 

बनाम

[field doSomething] // might work.. but will bite you eventually 
field = someObject; // almost certainly wrong anywhere outside a custom setter 

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

यदि इवर का थोड़ा अलग नाम है, तो पीछे की ओर _ संलग्न के साथ कहें, संकलक आपको रोक देगा और आपको स्पष्ट रूप से निर्णय लेगा: क्या मैं यहां संपत्ति या ivar को सीधे संदर्भित करना चाहता हूं?

(सभी कि कहा, मैं आलसी हूँ और अक्सर @synthesize field; करते हैं, और बाद में इसे बदलने के @synthesize field = field_; साथ जब मैं वास्तव में अलग इवर की जरूरत है, का कहना है कि जब यह कस्टम सेटर लेखन समय है।)

+0

आपके उत्तर के लिए धन्यवाद! – user1006198

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