2012-08-17 10 views
6

मानते हैं कि हमारी -init विधि केवल self पर संदेश आमंत्रित करती है, तो यह जांचना आम बात है कि self != nil संदेश nil का कोई प्रभाव नहीं है या नहीं?स्वयं की जांच क्यों करें! = Nil in -init जब संदेश शून्य का कोई प्रभाव नहीं पड़ता है?

चलो कहते हैं कि इस प्रकार हम एक प्रारंभकर्ता करते हैं:

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     [self doThis]; 
     [self setFoo:@"Bar"]; 
    } 

    return self; 
} 
इसके बजाय self जाँच की

, हम लिख सकते हैं:

- (id)init 
{ 
    self = [super init]; 
    [self doThis]; 
    [self setFoo:@"Bar"]; 

    return self; 
} 

अब अगर किसी कारण से [super init] रिटर्न nil, वहाँ कोई अंतर हो जाएगा जहां तक ​​मुझे पता है विधि के नतीजे में। फिर हम लगातार यह जांच क्यों करते हैं?

उत्तर

7

आप शून्य पर एक संदेश भेज सकते हैं, लेकिन आप शून्य के आवृत्ति चर तक नहीं पहुंच सकते हैं। आपको EXC_BAD_ACCESS अपवाद मिलेगा।

@implementation MyObject { 
    int instanceVariable; 
} 

- (id)init { 
    self = [super init]; 
    instanceVariable = 7; 
    return self; 
} 

अगर [super init] रिटर्न इस उदाहरण में शून्य क्या होता है:

एक वर्ग उदाहरण चर है कि विचार करें? आप एक शून्य सूचक से instanceVariable तक पहुंचने का प्रयास करेंगे और आपको अपवाद मिलेगा।

भले ही आप किसी भी आवृत्ति चर का उपयोग नहीं कर रहे हैं, फिर भी यदि आप self == nil की जांच नहीं करते हैं तो अन्य चीजें निश्चित रूप से गलत हो सकती हैं। आप malloc - आवंटित स्मृति या फ़ाइल हैंडल को आसानी से रिसाव कर सकते हैं, या खुद को ऐसी विधि से गुजर सकते हैं जो शून्य की अपेक्षा नहीं कर रहा है।

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

@implementation MyObject 

@synthesize someProperty; // assume it's an NSObject * 

- (id)init { 
    self = [super init]; 
    [self setSomeProperty:[[NSObject alloc] init]]; 
    return self; 
} 

यह एआरसी के तहत लीक नहीं होगा, भले ही self नहीं के बराबर है। मैन्युअल संदर्भ गिनती (एमआरसी) के तहत, यह उदाहरण रिसाव करेगा कि self शून्य है या नहीं, क्योंकि [NSObject alloc] से +1 को बनाए रखने के लिए कुछ भी नहीं है।

- (id)init { 
    self = [super init]; 
    [self setSomeProperty:[[[NSObject alloc] init] autorelease]]; 
} 

या इस:

- (id)init { 
    self = [super init]; 
    NSObject *object = [[NSObject alloc] init]; 
    [self setSomeProperty:object]; 
    [object release]; 
    return self; 
} 

न तो उन लोगों में से रिसाव हो जाएगा कि क्या self नहीं के बराबर है या नहीं

एमआरसी के तहत यह करने के लिए उचित तरीके से इस है।

- (id)init { 
    self = [super init]; 
    _someProperty = [[NSObject alloc] init]; 
    return self; 
} 
+0

यह एक संकेत है - सी में अपवाद नहीं हैं। –

+1

+1 हालांकि, महान जवाब। –

+0

यह एक सीपीयू अपवाद है, सी ++ अपवाद नहीं। '/ Usr/include/mach/upgrade_types.h' देखें। –

0

हैं [सुपर init] बारी वापसी नहीं के बराबर में किया था, तो आप अंत होगा संभवतः अधिक आवंटन:

आप सेटर विधि, इस तरह बाईपास हैं, तो आप सिर्फ अगर self नहीं के बराबर है दुर्घटना जाएगा ऑब्जेक्ट्स जिनका कभी भी उपयोग नहीं किया जाएगा, जब से आप स्वयं वापस आते हैं, तो आप शून्य वापस आ जाएंगे; तो उन वस्तुओं को रिहा नहीं किया जाएगा।

+0

तो आखिर में @rob सही है - यह वास्तविक कारण नहीं है। –

+0

@ user1606088 हालांकि निराश न हों। यह एक सुंदर सूक्ष्म मुद्दा है। –

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