2011-12-14 8 views
11

उद्देश्य-सी 2.0 में आवृत्ति उदाहरणों को विरासत में रखते हुए उप-वर्गों को self कीवर्ड का उपयोग करके मूल कक्षाओं में आवृत्ति चर का संदर्भ क्यों देना चाहिए?उद्देश्य-सी

इस उदाहरण पर विचार:

// a.h 
@interface MyClass : NSObject 
@property (nonatomic, retain) Object *myObject; 
@end 

// a.m 
@implementation MyClass 
@synthesize myObject; 
@end 


// b.h 
@interface AnotherClass : MyClass 
@end 

// b.m 
@implementation AnotherClass 
- (void) someMethod { 
    // error 
    // Object *obj = myObject; 

    // works 
    // Object *obj = self.myObject; 
} 
@end 
+2

यह [केविन Ballard के उत्तर] (http://stackoverflow.com/a/8511046/) द्वारा समझाया गया है [संश्लेषित ivars की दृश्यता क्या है?] (Http://stackoverflow.com/questions/8510464/) कुछ घंटों पहले से। –

उत्तर

11

आप वास्तव में एक चर निर्धारित नहीं किया है, आप केवल एक संपत्ति (जो परोक्ष एक चर कि निजी है परिभाषित करता है) को परिभाषित किया। और चूंकि संपत्ति सिर्फ विधि है, आपको डॉट सिंटैक्स की आवश्यकता है। ध्यान दें कि self.property[self property] जैसा ही है।

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

// a.h 
@interface MyClass : NSObject { 
    // Instance variables are "protected" by default, except if you 
    // use @private or @public. 
    Object *myObjectVar; 
} 

@property (nonatomic, retain) Object *myObject; 
@end 

// a.m 
@implementation MyClass 
@synthesize myObject = myObjectVar; 
@end 


// b.h 
@interface AnotherClass : MyClass 
@end 

// b.m 
@implementation AnotherClass 
- (void) someMethod { 
    // works 
    Object *obj = myObjectVar; 

    // works 
    obj = self.myObject; 

    // the same as self.myObject 
    obj = [self myObject]; 
} 
@end 

नोट अंतर है जब आप आवंटित : यदि आप अपने चर वस्तु स्वचालित रूप से नहीं बनी रहती है करने के लिए आवंटित।

myObjectVar = someObject; // not retained, old object not released! 
self.myObject = someObject; // old object released, new object retained 
[self setMyObject:someObject]; // same as the line above 

संपादित करें:: उल्लेख किया है कि संश्लेषित उदाहरण चर डिफ़ॉल्ट से निजी हैं के रूप में @Jason कोको द्वारा नोट लेकिन यह अगर आप संपत्ति का उपयोग बनी रहती है। और @NSGod सही है कि सामान्य उदाहरण चर संरक्षित डिफ़ॉल्ट रूप से सार्वजनिक रूप से तय किए गए हैं।

+1

'@ संश्लेषित 'गुण वास्तव में उनके नाम का एक ivar बनाते हैं, लेकिन वे एक' @ निजी 'ivar संश्लेषित करते हैं। आप कामों का उत्तर देते हैं क्योंकि आपने विशेष रूप से ivar बनाया है और सिंथेसाइज़र को कम प्रतिबंधित पहुंच स्तर के साथ सौंप दिया है, न कि सिंथेसाइज़र इवर उत्पन्न नहीं करते हैं। –

+0

मैंने यह नहीं कहा है कि सिंथेसाइज़र इवर उत्पन्न नहीं करते हैं, है ना? मेरी पहली वाक्य देखें। लेकिन यह स्पष्ट करने के लिए धन्यवाद कि वे निजी हैं। – DarkDust

+0

ओह, आप सही हैं। मैंने इसे अपने जल्दबाजी में गलत तरीके से छोड़ दिया, माफ करना! –

8

वे नहीं करते हैं, बशर्ते आप वास्तव में सुपरक्लस में एक इंस्टेंस वैरिएबल घोषित करें, बजाय इंस्टेंस वैरिएबल को संश्लेषित करने के लिए नई रनटाइम की क्षमता पर भरोसा करने के बजाय (एक्सेसर विधियों को संश्लेषित करने के अलावा)। उदाहरण परिवर्तनीय संश्लेषण पर अधिक जानकारी के लिए The Objective-C Programming Language: Runtime Difference देखें।

उदाहरण के लिए, सीधे उदाहरण चर का उल्लेख करने में सक्षम हो, तो आप निम्न परिवर्तन करने की आवश्यकता होगी:

@interface MyClass : NSObject 
@property (nonatomic, retain) Object *myObject; 
@end 

रहे हैं:

@interface MyClass : NSObject { 
// there is an implied @protected directive here 
    Object *myObject; 
} 

@property (nonatomic, retain) Object *myObject; 

@end 

डिफ़ॉल्ट रूप से, उदाहरण चर @protected हैं , जिसका मतलब वर्ग और कोई उप-वर्ग सीधे आवृत्ति चर का उपयोग कर सकते हैं। @protected ivars @public ivars से अलग हैं जिसमें आप -> का उपयोग करके उन तक नहीं पहुंच सकते हैं। @private इवर्स केवल उस वर्ग द्वारा पहुंचा जा सकता है जो उन्हें घोषित करता है। अधिक जानकारी के लिए The Objective-C Programming Language: The Scope of Instance Variables देखें।

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

  • कोई संबंधित समस्या नहीं^_^