2010-03-05 10 views
47

यह एप्पल के iPhone 'उपयोगिता आवेदन' टेम्पलेट से असंशोधित कोड है:ऑब्जेक्टिव-सी 'स्वयं' का उपयोग कब

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

MainViewController *aController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil]; 
self.mainViewController = aController; 
[aController release]; 

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 
[window addSubview:[mainViewController view]]; 
[window makeKeyAndVisible]; 

} 

जब mainViewControlleraController को सौंपा गया है, self कीवर्ड निर्दिष्ट किया जाता है:

self.mainViewController = aController; 

हालांकि, जब mainViewController के फ्रेम सेट किया गया है, self कीवर्ड की आवश्यकता नहीं है:

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 

अगर मैं पहला उदाहरण से self कीवर्ड निकालने, कार्यक्रम संदेश के साथ दुर्घटनाओं:

objc[1296]: FREED(id): message view sent to freed object=0x3b122d0 

मैं दूसरे उदाहरण के लिए self कीवर्ड जोड़ते हैं, कार्यक्रम ठीक चलाता है।

क्या कोई बता सकता है कि पहले मामले में self क्यों आवश्यक है, लेकिन दूसरा नहीं? मुझे लगता है कि दोनों मामलों में mainViewController एक ही आवृत्ति चर का जिक्र कर रहा है।

+0

इस प्रश्न का उत्तर पढ़ें: http://stackoverflow.com/questions/2302891/self-instance-var-performance-hit – Felixyz

उत्तर

47

स्वयं का उपयोग करके इस चर के लिए आपके वर्ग 'सेटटर "को इवर को बदलने के बजाए बुलाया जा सकता है।

[self setMainViewController:aController]; 

दूसरी ओर:

mainViewController = aController; 

सिर्फ mainViewController उदाहरण चर में परिवर्तन सीधे किसी भी अतिरिक्त कोड है कि UIApplication के setMainViewController में बनाया जा सकता है अधिक लंघन

self.mainViewController = aController; 

के बराबर है विधि, जैसे पुरानी वस्तुओं को जारी करना, नए बनाए रखना, आंतरिक चर अद्यतन करना आदि।

मामले में जहां अपने फ्रेम तक पहुँचने, आप अभी भी कॉल कर रहे हैं एक सेटर विधि में:

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 

के लिए विस्तारित:

[[mainViewController view] setFrame:[[UIScreen mainScreen] applicationFrame]]; 

आदर्श रूप में अपने कोड, भविष्य सबूत के लिए, आप भी ऐसा करना चाहिए इस मान को पुनः प्राप्त करते समय self.mainViewController (या [self mainViewController]) का उपयोग कर रहे हों। आम तौर पर, कक्षाओं को उनके "सेटर्स" की तुलना में अपने "गेटटर" विधियों में महत्वपूर्ण कोड होने की संभावना कम होती है, लेकिन यह अभी भी संभव है कि सीधे पहुंच से कोको टच के भविष्य के संस्करण में कुछ तोड़ सकता है।

+1

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

+5

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

+3

मुझे लगता है कि कम से कम एक अन्य अपवाद है जहां आप सीधे ivar तक पहुंच सकते हैं: dealloc में। इसके अलावा मुझे लगता है कि आपको हमेशा गेटर्स और सेटर्स के साथ स्वयं का उपयोग करना चाहिए। –

9

self कीवर्ड इंगित करता है कि आप सीधे मूल्य तक पहुंचने के बजाय संपत्ति गेटर/सेटर का उपयोग कर रहे हैं। यदि आप सिंक्रनाइज़ेशन का उपयोग करके गेटटर/सेटर को स्वत: जेनरेट करने देते हैं तो आपको पहले उदाहरण में स्वयं का उपयोग करना होगा क्योंकि ऑब्जेक्ट को केवल पॉइंटर-असाइन किए जाने के बजाय वहां रखा जाता है।

+0

कोई भी वास्तव में समझाया नहीं गया है आत्म परिवर्तनीय क्या है। मुझे लगता है कि यह सवाल का हिस्सा था। – Fab1n

+4

स्वयं यह पॉइंटर सी ++ के समान है। इसमें कक्षा का पता होता है। – Subrat

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