2013-03-26 4 views
9

का उपयोग करके यह बहुत कुछ पूछा गया है, लेकिन यह सवाल यह है कि आप इन तरीकों में से प्रत्येक का उपयोग कब करेंगे। कृपया सेटर और गेटर अनंत लूपआईओएस, iVar का उपयोग कर अंडरस्कोर बनाम सीधे

उदाहरण के अलावा अन्य उदाहरणों का उपयोग करें।

ज -
@property(nonatomic, strong)NSMutableArray* mutArray
मीटर -
@synthesize mutArray= _mutArray;

1) मैं चाहता हूँ होगा:
_mutArray = [[NSMutableArray alloc] init];
या
self.mutArray=[[NSMutableArray alloc] init];
मैं उनमें से प्रत्येक क्यों करना होगा, और क्या अंतर है ?!

2) मैं यह करने के लिए एक वस्तु को जोड़ना चाहते हैं ...
[_mutArray addObject:object];
या
[self.mutArray addobject:object];

और क्यों ?!

बहुत बहुत धन्यवाद!

उत्तर

12

आपको केवल init और dealloc में अपने आइवरों से निपटना चाहिए या जहां एक कार्यान्वयन विस्तार (जैसे एक्सेसर के अंदर, या जहां आपको वास्तव में स्मृति पता की आवश्यकता है) द्वारा पूरी तरह से आवश्यक है। उन स्थानों के अलावा, आपको हमेशा एक्सेसर का उपयोग करना चाहिए, जिसका अर्थ है [self foo]_foo के बजाय।

self.foo वास्तविक कॉल के आसपास सिंटैक्टिक चीनी है, जो [self foo] है। यह समझना महत्वपूर्ण है कि self.foo एक मानक ओबीजेसी संदेश भेजता है, और इसका अर्थ है [self foo] जैसा ही है। सम्मेलन के अनुसार, आपको गुणों का जिक्र करते समय केवल डॉट-सिंटैक्स का उपयोग करना चाहिए।

प्री-एआरसी, इवार्स का सीधा उपयोग मेरे अनुभव में दुर्घटनाओं का # 1 कारण था।एआरसी के बिना सीधे आईवर को आवंटित करते समय आप को खराब करने की संभावना प्रोग्राम के दायरे में 100% तक पहुंच जाती है।

एआरसी के बाद से, मैं अब भी तर्क देता हूं कि आपको हमेशा एक्सेसर्स (ऊपर दिए गए अपवादों के साथ) का उपयोग करना चाहिए, लेकिन कारण अधिक सूक्ष्म हैं। इसका मुख्य कारण यह है कि एक एक्सेसर को या तो मौजूदा वर्ग में, उप-वर्ग में, या केवीओ के माध्यम से अनुकूलित किया जा सकता है (जो आपके कोड के बाहर पूरी तरह से होता है)। यदि आप सीधे इवर तक पहुंचते हैं, तो आप इसे बाईपास करेंगे। उदाहरण के लिए, कहें कि संपत्ति आलसी ढंग से बनाई गई है (जो कि काफी आम है)। फिर यदि आप इसे बनाने से पहले ivar का उपयोग करते हैं, तो आपको सूक्ष्म बग मिल जाएगी। इसलिए आपको उस संपत्ति के लिए हमेशा एक्सेसर का उपयोग करना याद रखना होगा। इसी तरह, आप setNeedsDisplay पर कॉल कर सकते हैं या अधिसूचना पोस्ट कर सकते हैं, या जैसे।

यदि आपके पास एक सरल नियम है जो कहता है "मैं हमेशा एक्सेसर्स का उपयोग करता हूं" तो कोड को देखना आसान है और यह सही है। कुछ मामलों में आपको एक्सेसर को बाधित करने की आवश्यकता है, _ कहता है "अरे, यहां ध्यान दें, मैं कुछ अजीब कर रहा हूं।"

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

तो पोस्टर एआरसी भी एक्सेसर्स का उपयोग करके लगातार रक्षात्मक प्रोग्रामिंग है और मैं अत्यधिक अनुशंसा करता हूं।

+0

वैसे यह रग्गर के जवाब के साथ सुपर विवादित है! आप सेटटर के माध्यम से अतिरिक्त अतिरिक्त जोड़ा के बारे में क्या सोचते हैं? और यह भी तथ्य कि अन्य लोग कोड के साथ काम कर रहे हैं और सेटर्स/गेटर्स को अप्रत्याशित परिणामों के कारण बदल रहे हैं? – jgvb

+0

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

+0

कभी-कभी यह आश्चर्यजनक परिणाम (उदाहरण के लिए अक्सर कुछ बार फिर से गणना करना) का कारण बनता है, लेकिन उन दुष्प्रभावों को लगभग हमेशा मेरे अनुभव में डीबग करना बहुत आसान होता है, इस तथ्य की तुलना में कि आपको पता नहीं था कि आपको सेटिंग के बाद 'setNeedsDisplay' को कॉल करना था इवर इससे चीजों की ओर इशारा होता है कि "जब वे ऐसा नहीं करते हैं, तो वे काम करते हैं" जो डीबग करना बेहद मुश्किल है। एक एक्सेसर चलाना जब आपको पता नहीं था कि यह स्टैक ट्रेस में दिखाई देगा। एक एक्सेसर चलाने में विफल होने पर आपको नहीं पता था कि आपको दौड़ने की जरूरत है .... यह खोजना मुश्किल है। –

0

_mutArray iVar है, self.mutArray आपके द्वारा बनाए गए गेटर्स और सेटर्स के माध्यम से संपत्ति का उपयोग करता है जब आप संपत्ति को संश्लेषित करते हैं। आप इन गेटर्स और सेटर्स को उचित कस्टम सामान पर ओवरराइट कर सकते हैं। आपके उदाहरण में, आप संपत्ति मजबूत पर सेट हैं, जो आपकी संपत्ति को बनाए रखती है। तो self.mutarray = [[NSMutableArray alloc] init]; कुछ इस तरह (जब तक आप अधिक से लिखने संपत्ति के सेटर) करना होगा:

-(void)setMutarray:(NSMutableArray*)_mutArray{ 
    if(_mutArray != mutArray){ 
     [mutArray release]; 
     mutArray = nil; 
     mutArray = [_mutArray retain]; 
    } 
} 

एक सरणी के लिए वस्तुओं जोड़ने तुम सिर्फ इवर, नहीं संपत्ति जब तक आप गेटर में कुछ कस्टम कर रहे हैं उपयोग करना चाहते हैं के लिए । उदाहरण के लिए आप कर रहे हैं गेटर इस प्रकार दिखाई देंगे:

-(NSMutableArray*)mutArray{ 
    if(!mutArray){ 
     self.mutArray = [[[NSMutableArray alloc] init] autorelease]; 
    } 
    return mutArray; 
} 
इस तरह से

आप यह सुनिश्चित कर सकता है कि आप हमेशा के लिए वस्तुओं को जोड़ने के लिए कोई वास्तविक सरणी था। यदि ऐसा है तो आप [self.mutArray addObject: ऑब्जेक्ट] का उपयोग करना चाहते हैं;

तो, जब तक कि आप गेटर या सेटर में कुछ कस्टम नहीं करना चाहते हैं, तो आप केवल iVar तक पहुंचना चाहते हैं।

+0

क्यों मैं सेटर और गेटर के माध्यम से जाना जब तक कि मैं अनुकूलित नहीं करना चाहते हैं? – jgvb

+0

आप सेटर के माध्यम से नहीं जाना चाहते हैं क्योंकि यह एक बरकरार रखेगा। साथ ही, यदि अन्य लोग कोड के साथ काम कर रहे हैं, तो वे गेटटर या सेटर में कुछ कर रहे हैं जिसके लिए आप लेखांकन नहीं कर रहे हैं। –

+0

आपको बहुत धन्यवाद – jgvb

0

selfkeywordthiskeywordJAVA में की तरह है।

यह वर्तमान ऑब्जेक्ट तक पहुंच है और यह किसी ऑब्जेक्ट के लिए पॉइंटर है।

for more info about self read this tutorial

_ObjeNameObjective c

उदाहरण चर कार्यान्वयन में घोषित परोक्ष छिपे हुए हैं में iVar कहा जाता है (प्रभावी रूप से निजी) और दृश्यता - @public, @protected and @private बदला नहीं जा सकता संकलक त्रुटियों (उत्पादन नहीं करते हैं साथ वर्तमान क्लैंग कम से कम) लेकिन अनदेखा कर रहे हैं।

उदाहरण के लिए :

अलग के बीच

1)NSString *someString = _name;

2)NSString * someString = self.name;

मान लें कि आपके मीटर फ़ाइल इस पंक्ति में है (तथा नाम_ को पहुँच निर्देशित करने के लिए)

@synthesize name = _name; 

इसका मतलब यह है कि संपत्ति name (self.name) जब आप इसे तक पहुँचने का प्रयास चर नाम_ का उपयोग करेगा किसी भी ओवरराइड तरीकों की जरूरत नहीं है।इस मामले में self.name


नाम_ के बराबर है लेकिन अगर आप इस तरह के नाम के लिए गतिशील संपत्ति, कुछ है:

-(NSString)name{ 
    return @"1234"; 
} 

तो कोई फर्क नहीं है। self.name हमेशा 1234 लौटाएगा, लेकिन _name इस मान के बराबर नहीं हो सकता है।

उदाहरण:

_name = @"555"; 
NSLog(_name); 
NSLog(self.name); 

परिणाम:

2012-02-09 14:27:49.931 ExampleApp[803:207] 555 
2012-02-09 14:27:49.933 ExampleApp[803:207] 1234 

Above Example I Got From this Question.

+2

यह कहकर कि 'स्वयं' 'डेवलपर्स' की तरह है, यह नए डेवलपर्स के लिए बेहद भ्रमित है। जावा पर इसका इस्तेमाल किया जा सकता है। ओबीजेसी में 'स्वयं' का कभी भी निहित नहीं है। यह बहुत भ्रम पैदा करता है जब पूर्व जावा डेवलपर्स सोचते हैं कि '_name' और 'self.name' का मतलब बिल्कुल वही है। वे कभी भी समान नहीं होते हैं, वे हमेशा अलग असेंबलर कोड उत्पन्न करेंगे, वे एक ही परिणाम लौटने के लिए हो सकते हैं। –

+0

@RobNapier +1। मैं जावा पृष्ठभूमि से ओबीजेसी में आया हूं और यह 'इस' और 'स्वयं' के साथ तुलना भी कर रहा था, हालांकि संबंधित, एक अलग बात है। – Petar

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