2012-04-27 5 views
5

ऐसा लगता है कि एक पुस्तक के कोड उदाहरण में, init हमेशा परिभाषित किया जाता है ताकि यह जांचने के लिए सावधान रहें कि self मौजूद है या नहीं।उद्देश्य-सी में, [[myView alloc] init] से निपटने के लिए कैसे नील?

-(id) init { 

    self = [super init]; 
    if (self) { 
     // initialize 
    } 
    return self; 
} 

हालांकि, बदले में, कोड में से कोई भी यह जांच नहीं करता कि ऑब्जेक्ट मौजूद है या नहीं। लेकिन इसे जांचना चाहिए, और इसे कैसे संभाला जा सकता है? यदि वस्तु मौजूद नहीं हो सकती है, तो क्या इसका मतलब यह है कि सिस्टम स्मृति से गंभीरता से बाहर है, और यहां तक ​​कि एक त्रुटि संदेश पॉप अप करना भी असंभव होगा?

+0

यह वास्तव में एक बहुत अच्छा सवाल है। मुझे पता है कि मैं कभी भी इस तरह के फ़ंक्शन के परिणाम से कुछ प्राप्त नहीं करता हूं, मुझे लगता है कि आवंटन/init काम करता है (जब तक कि कुछ ऐसा नहीं होता है जो त्रुटि और त्रुटि करता है, जो उस चीज़ का प्रतिनिधित्व करता है जिसमें असफल होने का मौका होता है)। वास्तव में एक बहुत ही दिलचस्प सवाल है। – RonLugge

+0

संभावित डुप्लिकेट [उद्देश्य-सी में मुझे क्यों जांचना चाहिए कि क्या स्वयं = \ [सुपर इनिट \] शून्य नहीं है?] (Http://stackoverflow.com/questions/1287950/in-objective-c-why-should- i-check-if-self-super-init-is-not-nil) – omz

उत्तर

4

हालांकि, बदले में, कोड में से कोई भी यह जांच नहीं करता कि ऑब्जेक्ट मौजूद है या नहीं। लेकिन इसे जांचना चाहिए, और इसे कैसे संभाला जा सकता है?

आमतौर पर, nil वापस आने पर उप-वर्गों द्वारा त्रुटि प्रबंधन को अनदेखा किया जाता है। nil वापस लौटाए जाने पर त्रुटि प्रबंधन आमतौर पर कॉलर को छोड़ दिया जाता है। के रूप में मुहावरेदार -init में प्रदर्शन:

- (id)init { 
    self = [super init]; 
    if (self) { 
    // initialize 
    } 
    return self; 
} 

साथ ही, अगर आधार से पुनर init में self, तो self पुन: असाइन किया जाता है (self = [super init];)। बहुत अच्छा काम करता है।

आप super के प्रारंभकर्ता के परिणाम के self आवंटित करने के लिए असफल हो या आप nil के लिए, तो आप एक झूलने को पकड़ने में किया जा सकता है/deallocated सूचक (EXC_BAD_ACCESS) की जांच करने में विफल, और आप अपने ivars प्रारंभ नहीं हो सकता है यदि ठीक से (यदि EXC_BAD_ACCESS का सामना नहीं किया गया था तो आप उन्हें प्रभावी रूप से किसी अन्य क्षेत्र में असाइन करेंगे)। और अधिक विस्तार में

दो मामलों:

विफल

- (id)init { 
    [super init]; 
    if (self) { 
    // self was not reassigned. if super returned an object other 
    // than self, then our ivar would be freed, reused, or sitting 
    // in an autorelease pool, and the returned instance's ivar 
    // would not be assigned -- we wouldn't know the address. 
    ivar = 1; 
    } 
    return self; 
} 

विफल के लिए नहीं के बराबर

- (id)init { 
    self = [super init]; 
    // super returned nil. ivar is an invalid region: 
    ivar = 1; 
    return self; 
} 

जाँच करने के लिए आत्म आवंटित करने के लिए और हाँ, मैं दोनों को देखा है इन।


तो वस्तु मौजूद नहीं कर सकते, इसका मतलब यह है सिस्टम स्मृति से बाहर गंभीरता से है, और यहां तक ​​कि ऊपर पॉपिंग एक त्रुटि संदेश भी असंभव हो जाएगा?

बिलकुल नहीं। कई प्रारंभकर्ता nil को "इस संदर्भ में नहीं कर सकते" कहने के लिए वापस लौटते हैं, या यदि कोई साधारण पैरामीटर त्रुटि है।

+0

क्षमा करें, मुझे समझ में नहीं आता कि अगर आप शून्य की जांच नहीं करते हैं तो आपको एक खतरनाक सूचक कैसे होगा। यदि आप शून्य की जांच नहीं करते हैं, तो यदि आप नील आते हैं तो उन्हें प्रभावी रूप से संदेश भेजना होगा और उन्हें अनदेखा कर दिया जाएगा। – borrrden

+0

आह, मैं देखता हूं कि यह वास्तव में दूसरा भाग (स्वयं को पुन: असाइन करना) है जिसके बारे में आप बात कर रहे हैं। ^^; – borrrden

+0

@borrrden मुझे लगता है कि मैंने आपके लिए अपडेट किया है :) हाँ, संदेश * सुरक्षित हो सकता है, अगर स्वयं शून्य हो और आप अपने प्रारंभकर्ता में संदेश भेज रहे थे। हालांकि, प्रारंभिकरण और dealloc विशेष आंशिक रूप से निर्मित राज्य हैं। लोग दोनों पक्षों के लिए बहस करते हैं, लेकिन प्रत्यक्ष प्रारंभिकरण आमतौर पर इनिट/डेलोक में एक्सेसर्स का उपयोग करने के बजाय किसी ऑब्जेक्ट को प्रारंभ करने का सुरक्षित तरीका होता है। प्रदर्शन के रूप में, शून्य के लिए जांच करने में विफल भी एक जोखिम है। – justin

3

कि इस प्रणाली का क्या मतलब है गंभीरता से स्मृति से बाहर

नहीं, एक विफलता स्मृति को आबंटित करने में आम तौर पर कारण होगा + विफल alloc है, -init नहीं।

असल में, यह एक इनिट विधि के लिए बहुत असामान्य है जिसमें विफल होने के लिए कोई तर्क नहीं है। आम तौर पर यदि आप अमान्य तर्क पारित कर चुके हैं तो आम तौर पर init विधियां शून्य वापस आ सकती हैं, उदाहरण के लिए NSString's -initWithContentsOfFile: अगर वह फ़ाइल पथ की सामग्री को लोड करने में विफल रहा है, तो यह शून्य हो सकता है जिसे इसे आरंभ किया जाना था।

शायद ऐसा कुछ है जिसे आप जांचना चाहते हैं यदि आप init की विफलता के लिए एक महत्वपूर्ण संभावना से अवगत हैं, अन्यथा, आपको ऑब्जेक्ट का उपयोग करने के साथ ही आगे बढ़ना चाहिए।

+0

इसके अलावा, आईओएस पर, अगर सिस्टम मेमोरी से गंभीरता से बाहर है तो आप को जब्त कर दिया जाएगा। –

+0

@ केविनबल्लार्ड, हाँ, स्मृति आवंटन विफल होने से पहले ऐप को मार दिया जाएगा। और ओएस एक्स पर, 64 बिट में इतनी बड़ी वर्चुअल मेमोरी स्पेस है कि यह बहुत अच्छी तरह से अक्षम है कि एक ऐप मेमोरी से बाहर हो जाएगा। – joerick

+0

आईओएस वर्चुअल मेमोरी के रूप में छोड़ी गई फ्लैश मेमोरी का उपयोग करेगा? (जैसे कि 16 जीबी आईफोन में 3 जीबी मुफ्त है) ... हालांकि, मेरा आईफोन स्वचालित डाउनलोड के कारण गाने से भरा हुआ है कि केवल 20 एमबी मुफ्त है। –

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