2013-01-01 3 views
7

संभव डुप्लिकेट:
How does an underscore in front of a variable in a cocoa objective-c class work?self.variableName बनाम _variableName बनाम @sysnthesize variableName


नोट: लोगों इस समझने की कोशिश कर चारों ओर से खुदाई के लिए, मैं मेरे भ्रम के स्रोत का पता लगाया। ज में, मैं था:

... 
@interface myClass : parentClass { 
className *variableName: 
} 

@property (strong, nonatomic) className *variableName; 
... 

यह self.variableName और _variableName मीटर में दो अलग-अलग चर जा रहा है की ओर जाता है। क्या मैं जरूरत थी:

... 
@interface myClass : parentClass { 
className *_variableName: 
} 

@property (strong, nonatomic) className *variableName; 
... 

फिर, वर्ग 'मीटर में, self.variableName और _variableName बराबर


नया में, Xcode 4.5+ iOS 5.0 को लक्षित कर रहे हैं, एआरसी के साथ, + प्रोजेक्ट, क्या _variableNameself.variableName बनाम पुरानी शैली @synthesize variableName बनाम _variableName का उपयोग करने के लिए एक विशिष्ट लाभ (रनटाइम दक्षता, गति, इत्यादि) है?

मेरे समझ के साथ कि Xcode 4.5+ एक डिफ़ॉल्ट एक्सेसर _variableName कि self.variableName के बराबर है और केवल कारणों का उपयोग नहीं @synthesize variableName Ivars और पारित-इन वैरिएबल, सही बीच भ्रम की स्थिति से बचने के लिए है पैदा करेगा है?

मेरे लिए, केवल i12ar तक पहुंचने के लिए self.variableName का उपयोग करके सबसे सरल और स्पष्ट लगता है कि आप किस चर के लिए देख रहे हैं। _ बनाम self. टाइप करने के अलावा, _variableName का उपयोग करने का कोई फायदा है?

+1

और यहाँ है एक और 16: http://stackoverflow.com/q/5582448/ http://stackoverflow.com/q/6049269/ http://stackoverflow.com/q/2371489/ http://stackoverflow.com/q/7174277/ http://stackoverflow.com/q/5659156 http://stackoverflow.com/q/837559/ http://stackoverflow.com/q/6146244/ http: //स्टैक ओवरफ़्लो।कॉम/क्यू/10651535/ http://stackoverflow.com/q/6124109/ http://stackoverflow.com/q/8145373/ http://stackoverflow.com/q/3521254/ http: // stackoverflow.com/q/6064283/ http://stackoverflow.com/q/9696359/ http://stackoverflow.com/q/5521499/ http://stackoverflow.com/q/5466496/ http: //stackoverflow.com/q/2114587/ –

+0

मेरा बुरा। मैं 'अंडरस्कोर' वर्तनी-आउट की तलाश करने के बारे में सोचता हूं। उस ने कहा, कुछ संभावित डुप्लिकेशंस को स्पॉट-चेकिंग, मुझे कुंजी-मूल्य अवलोकन, बाइंडिंग और थ्रेड-सुरक्षित एक्सेस (परमाणु) के साथ संभावित मुद्दों का कोई भी/न्यूबी-सबूत उल्लेख नहीं देखा गया है यदि _variableName का उपयोग बनाम स्वयं ।चर का नाम। एक (4088801) ने संभावित समस्या का उल्लेख किया है यदि _variableName में निर्दिष्ट ऑब्जेक्ट को इसके बजाय self.variableName का उपयोग करके साझा और अनुशंसित किया जाता है। –

+0

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

उत्तर

15

मेरे समझ है कि Xcode 4.5+ एक डिफ़ॉल्ट एक्सेसर "_variableName" कि self.variableName और केवल कारणों के बराबर है उपयोग करने के लिए नहीं "@synthesize variableName" Ivars और बीच भ्रम की स्थिति से बचने के लिए है पैदा करेगा पारित कर दिया-इन चर, सही?

इस मामले में, _variableName, एक्सेसर नहीं है, यह एक इवर कि स्वचालित रूप से संकलक द्वारा उत्पन्न और स्वचालित रूप से @synthesized setters और getters में प्रयोग किया जाता है है। आम तौर पर, जब भी संभव हो तो एक्सेसर्स का उपयोग करना सबसे अच्छा माना जाता है (यानी self.variableName) ताकि महत्वपूर्ण मूल्य अवलोकन और बाइंडिंग जैसी चीजें उस संपत्ति के लिए काम कर सकें।

जब आप सीधे ivar तक पहुंचते हैं, तो इसे सीधे मेमोरी एक्सेस के माध्यम से एक्सेस किया जाता है, वैसे ही आप एक स्ट्रक्चर में डेटा तक पहुंच सकते हैं। यह केवल उस वस्तु के लिए पॉइंटर लेता है जो ivar का मालिक है, मेमोरी पता ऑफसेट करता है और उस स्थान पर स्मृति को पढ़ने या लिखने का प्रयास करता है। सेट या कि संपत्ति प्राप्त करने के लिए डॉट नोटेशन (self.variableName) एक्सेसर तरीकों का उपयोग कर कॉल और जैसे रास्ते में अलग अलग बातें, के एक नंबर कर सकते हैं:

1) लॉकिंग: संपत्ति में इस्तेमाल किया जा करने के लिए जा रहा है, तो एकाधिक धागे और atomic संपत्ति है, रनटाइम स्वचालित रूप से यह सुनिश्चित करने के लिए कुछ लॉकिंग करेगा कि संपत्ति को एकाधिक थ्रेड से एक ही समय में एक्सेस नहीं किया जाता है। यदि आपकी ऑब्जेक्ट का उपयोग कई धागे पर नहीं किया जाता है, तो आप अपनी संपत्ति घोषणा में nonatomic संकेत दे सकते हैं ताकि संश्लेषित एक्सेसर्स लॉकिंग को छोड़ दें।

2) मुख्य मान सूचनाएं: प्रॉपर्टी की डिफ़ॉल्ट setters -willChangeValueForKey: और -didChangeValueForKey: फोन है, जो बाहर सूचनाएं भेजता है जब संपत्ति बदल जाता है। यदि बाइंडिंग का उपयोग किया जाता है, और किसी अन्य कुंजी-मूल्य अवलोकन के लिए कुछ भी ठीक से अपडेट करना आवश्यक है।

3) कस्टम एक्सेसर व्यवहार: यदि आप अपने स्वयं के सेटर्स और गेटर्स लिखते हैं, तो आप उन कस्टम सामानों को लागू करते हैं जिन्हें आप लागू करते हैं।

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

इसके अतिरिक्त, यदि आप सीधे ivars तक पहुंच रहे हैं और अपनी कक्षा को श्रेणियों या उप-वर्गों में पुन: सक्रिय कर रहे हैं, तो यह गन्दा हो जाता है क्योंकि आपको आमतौर पर ivar को @protected चर के रूप में घोषित करना होता है। यदि आप एक्सेसर्स का उपयोग कर रहे हैं तो आपको ऐसा करने की ज़रूरत नहीं है।

आम तौर पर, मैं केवल init, dealloc, और संपत्ति के एक्सेसर में सीधे ivars तक पहुंचने का प्रयास करता हूं। बहुत से इंजीनियर अंगूठे के इस नियम से जाते हैं क्योंकि कभी-कभी एक्सेसर्स में होने वाली कस्टम सामग्री अप्रत्याशित व्यवहार कर सकती है जबकि ऑब्जेक्ट init 'आईएनजी या dealloc' आईएनजी है। उदाहरण के लिए, यदि एक्सेसर्स में कुछ भी retain या release आपकी ऑब्जेक्ट का कारण बनता है या यहां तक ​​कि शून्यिंग कमजोर संदर्भ भी बनाता है, तो dealloc में उपयोग होने पर यह क्रैश का कारण बन जाएगा।

5

नवीनतम एक्सकोड @synthesize वैकल्पिक है। डिफ़ॉल्ट रूप से, को छोड़ते हुए @synthesize उदाहरण के लिए, लेखन

@synthesize someName = _someName; 

उपयोग करने के लिए @synthesize नाम बदलने संपत्ति के मूल्य की दुकान के लिए बनाया उदाहरण चर है एकमात्र कारण के रूप में ही है

@synthesize someName = someSpecialName; 

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

+0

बस आपके उत्तर और @eyebrowsoffire, _variableName के आधार पर पैडेंटिक होने के लिए, तेज़ हो सकता है, लेकिन self.variableName सुरक्षित है? –

+0

@RayatERISCorp "सुरक्षित" इस संदर्भ में अविकसित है, लेकिन यदि आपका इरादा एक सिंक्रनाइज़ तरीके से किसी संपत्ति का उपयोग करना था (यानी यह 'परमाणु' है) तो उत्तर हाँ है, यह सुरक्षित है। असल में, दूसरी तरफ (यानी '_variableName' के लिए सीधे जा रहा है) बस अतिरिक्त लॉकिंग के बिना काम नहीं करता है। – dasblinkenlight

+0

गोचा। "सुरक्षित" से मेरा मतलब है "मेरे कोड में कुछ अप्रत्याशित बग ट्रिगर करने की संभावना कम है जो मुझे ऐसा करने के लिए बहुत अधिक समय तक डिबगिंग छोड़ देगी क्योंकि _variableName का उपयोग करके स्वचालित रूप से कुछ क्रियाओं को स्वचालित रूप से लात नहीं दिया जाता है जो self.variableName करता है।" –

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