2012-05-02 9 views
9

मैं हाल ही में Xcode 4.3.2 के लिए अद्यतन किया और पाया कि मैं अभी की तरह @implementation ब्लॉक के अंदर निजी उदाहरण चर घोषणा कर सकते हैं किया है:क्या उद्देश्य-सी में निजी आवृत्ति चर को परिभाषित करने का यह एक नया तरीका है?

@interface TestClass : NSObject 
@property (nonatomic, copy) NSString *testProp; 
@end 

@implementation TestClass { 
    NSString *_testPropStore; 
} 

- (NSString *)testProp { return _testPropStore; } 
- (void)setTestProp:(NSString *)testProp { _testPropStore = [testProp copy]; } 

- (id)init { 
    if (self = [super init]) { 
     _testPropStore = nil; 
    } 
    return self; 
} 

@end 

सूचना @implementation अंदर NSString *_testPropStore लाइन ब्रेस ब्लॉक।

मैं भी निम्न कोड के साथ परीक्षण किया है:

TestClass *c1 = [[TestClass alloc] init]; 
TestClass *c2 = [[TestClass alloc] init]; 

c1.testProp = @"Hello"; 
c2.testProp = @"World"; 

NSAssert(c1.testProp == c2.testProp, @"It's working!"); 

कौन सा अच्छा काम करने लगता है। (यानी, ऐप एनएसएसएसएसएसर्ट लाइन पर "यह काम कर रहा है" संदेश से दुर्घटनाग्रस्त हो जाता है।)

तो यह निजी उदाहरण चर घोषित करने के लिए उद्देश्य-सी की एक नई विशेषता है? चूंकि मैंने इसे दुर्घटना से खोजा है, इसलिए मुझे यह जानना अच्छा लगेगा कि यह केवल निजी आवृत्ति चर घोषित करने के लिए है या क्या कोई दुष्प्रभाव होगा जिसके बारे में मुझे पता नहीं है?

मुझे कोई प्रासंगिक दस्तावेज नहीं मिला क्योंकि private शब्द के साथ इस प्रकार के अधिकांश प्रश्नों को सिर्फ एक निजी एक्सटेंशन श्रेणी पर घोषित करने के तरीके के उत्तर के साथ समाप्त हो गया है।

उत्तर

19

यह वास्तविक है, यह नया तरीका है, * यह बहुत अच्छा है, और, हाँ, यह दस्तावेज़ों में है।

एक वर्ग की परिभाषा अपने घोषणा की तरह बहुत ज्यादा संरचित है: The Objective-C Programming Language है, जो हम भाषा के लिए एक वास्तविक कल्पना होने के लिए मिलता है के रूप में के रूप में करीब है, कहने के लिए निम्नलिखित है। यह @implementation निर्देश के साथ शुरू होता है और @end निर्देश के साथ समाप्त होता है। इसके अलावा, वर्ग @implementation निर्देश के बाद कोष्ठकों में उदाहरण चर घोषित कर सकता है:

@implementation ClassName 
{ 
    // Instance variable declarations. 
} 
// Method definitions. 
@end 

वहाँ भी एक ऐतिहासिक टिप्पणी एक छोटे तरीके कि लिंक से वापस आ गया है, इस तथ्य को संबोधित कर रहे हैं कि हम में ivars घोषित करने के लिए किया करते थे इंटरफ़ेस ब्लॉक:

ऐतिहासिक रूप से, इंटरफ़ेस को कक्षा के आवृत्ति चर के घोषणाओं की आवश्यकता होती है, डेटा संरचनाएं जो कक्षा के प्रत्येक उदाहरण का हिस्सा हैं। ... इंस्टेंस वैरिएबल एक कार्यान्वयन विवरण का प्रतिनिधित्व करते हैं, और आमतौर पर कक्षा के बाहर ही नहीं पहुंचाया जाना चाहिए। इसके अलावा, आप उन्हें कार्यान्वयन ब्लॉक में घोषित कर सकते हैं या घोषित गुणों का उपयोग करके उन्हें संश्लेषित कर सकते हैं। आम तौर पर, आपको सार्वजनिक इंटरफ़ेस में इंस्टेंस चर घोषित नहीं करना चाहिए और इसलिए आपको ब्रेसिज़ को छोड़ना चाहिए।

गोपनीयता के सवाल के लिए, हाँ, ये चर वास्तव में निजी हैं - वे @private निर्देश के साथ इंटरफ़ेस में घोषित इवर की तरह कार्य करते हैं। इसका अर्थ यह है कि उप-वर्ग डिफ़ॉल्ट रूप से उन तक नहीं पहुंच सकते हैं।उनकी दृश्यता बदला जा सकता है, हालांकि, या तो @protected या का उपयोग कर (यदि आवश्यक हो कुछ विचित्र कारण के लिए) @public:

@interface Stuper : NSObject 
@end 

@implementation Stuper 
{ 
    @protected 
    NSString * sangfroid; 
} 
@end 

@interface Stub : Stuper 
- (void)setSangfroid: (NSString *)newSangfroid; 
@end 

@implementation Stub 

- (void)setSangfroid: (NSString *)newSangfroid { 
    sangfroid = [newSangfroid copy]; 
} 

* आप का उपयोग करने के बजना> 3.0, मुझे विश्वास है, तो यह है कि कुछ ही महीनों है इस पोस्ट के रूप में पहले। जीसीसी ऐसा नहीं करेगा।

+0

मैं अधिक उत्सुक हूं कि यह हुड के नीचे कैसे किया जाता है। ऑब्जेक्टिव-सी रनटाइम कैसे जानता है कि हेडर की अपूर्ण परिभाषा है तो कक्षा के लिए कितनी मेमोरी आवंटित की जाती है? – mpontillo

+0

पोस्ट करने के लिए यह एक अच्छा सवाल होगा। यह लगभग निश्चित रूप से ["गैर-नाजुक ivars"] (http://www.sealiesoftware.com/blog/archive/2009/01/27/objc_explain_Non-fragile_ivars.html) के साथ कुछ करने के लिए है। –

+0

एफवाईआई, आपके उत्तर में लिंक मेरे लिए टूटा हुआ प्रतीत होता है। –

2

यह बहुत नया है और यह तब तक मान्य है जब तक आपको आवश्यक किसी भी कंपाइलर का समर्थन नहीं होता है।

आपकी निर्भरताओं को कम करने के लिए यह बहुत अच्छा है - इसमें शामिल हैं और आगे बड़े पैमाने पर कार्यान्वयन फ़ाइल में हो सकते हैं। इस कारण से, और यदि आपके द्वारा उपयोग किए जाने वाले सभी कंपाइलर्स इसका समर्थन करते हैं, तो @interface ब्लॉक की तुलना में यह आपके इवर के लिए बेहतर जगह है।

एक अंतिम चेतावनी यह है कि हमारे वर्तमान (मई 2012) डिबगर्स इसका समर्थन नहीं करते हैं।

+2

डिबगर्स के बारे में बहुत अच्छी बात है। Lldb.devel सूची पर इसके बारे में एक छोटा सा धागा है: http://comments.gmane.org/gmane.comp.debugging.lldb.devel/624 –

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

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