2014-09-01 9 views
5

स्विफ्ट में, वर्तमान कक्षा के सभी गुणों को प्रारंभ करने के बाद सुपर के प्रारंभिककर्ता को बुलाया जाना चाहिए। हालांकि यह उद्देश्य-सी init के लिए नहीं किया गया है, जहां वर्तमान कक्षा में गुणों को शुरू करने से पहले सुपर इनिट को पहले कहा जाता है।स्विफ्ट सुपर प्रारंभकर्ता

स्विफ्ट इसे लागू करके रोकने के लिए क्या समस्याएं हैं? उद्देश्य-सी मुद्दों से बचने में सक्षम क्यों है स्विफ्ट रोकने की कोशिश कर रहा है?

+0

मैं यह भी उल्लेख कर सकता हूं कि उद्देश्य-सी में आपको सुपरक्लस प्रारंभकर्ता को कॉल करने के बाद राज्य * प्रारंभ करना चाहिए - क्योंकि सुपरक्लस प्रारंभकर्ता एक अलग ऑब्जेक्ट वापस कर सकता है जिस पर ऑब्जेक्ट को बुलाया जाता है। इसलिए, यदि आप सुपरक्लस प्रारंभकर्ता को कॉल करने से पहले कुछ राज्य सेट करते हैं, तो यह गलत ऑब्जेक्ट (मूल 'स्वयं', बाद में 'स्वयं' नहीं) पर सेट किया जाएगा।स्विफ्ट में यह समस्या नहीं है क्योंकि स्विफ्ट में प्रारंभकर्ता किसी अन्य वस्तु को वापस नहीं कर सकते हैं जिसे इसे बुलाया जाता है (उद्देश्य-सी से आयातित प्रारंभकर्ताओं को छोड़कर)। – newacct

उत्तर

10

सभी सदस्यों को प्रारंभ?

यह एक अच्छा सवाल है, और उद्देश्य-सी इससे बच नहीं पाया।

समस्या यह है कि जब आप प्रारंभिक विधि के अंदर होते हैं, तो वस्तु तकनीकी रूप से आंशिक रूप से निर्मित स्थिति में होती है। Bryan's post क्यों एक महान (हालांकि योगदान हुआ) उदाहरण है। सामान्य मुद्दा यह है कि यदि एक सुपर क्लास के प्रारंभकर्ता एक विधि का आह्वान करता है, तो उप-वर्ग इस विधि को ओवरराइड कर सकता है। वह, अपने आप में, एक बुरी बात नहीं है। समस्या तब उत्पन्न होती है जब ओवरराइड विधि मानती है कि ऑब्जेक्ट पूरी तरह से बनाया गया है।

हालांकि, चूंकि ऑब्जेक्ट अभी भी प्रारंभकर्ताओं के आह्वान के बीच में है, ऐसा नहीं है। ऑब्जेक्ट पूरी तरह से [super init] रिटर्न तक कॉल तक पूरी तरह से निर्मित नहीं होता है और ऑब्जेक्ट का वर्ग इसके प्रारंभिक कोड को निष्पादित करता है।

dealloc तरीकों के साथ किसी समस्या से जूझ रहे है: यदि आप अपने -dealloc विधि के अंदर विधियां प्रारंभ, उन तरीकों, मान सकते हैं कि वस्तु पूर्ण निर्माण किया है जबकि वास्तव में इस आंशिक रूप से deconstructed जा सकता है। यह एआरसी के तहत एक सौदे के रूप में बड़ा नहीं है, लेकिन यह अभी भी कुछ बहुत सूक्ष्म बग का कारण बन सकता है।

स्विफ्ट के साथ

, निर्णय इस नियम को लागू करके समस्याओं के इन वर्ग से बचने के लिए किया गया था:

बार जब आप super कॉल करने के लिए तय करके, बुला वर्ग किसी भी वर्ग विशेष के प्रारंभ समाप्त कर दिया है चाहिए।

इस नियम का एक प्रकार है:

आप जब तक आप super के प्रारंभकर्ता कहा जाता है विधियां प्रारंभ नहीं हो सकता है।

इस नियम के साथ, आप ऊपर वर्णित समस्या में कभी भी भाग नहीं पाएंगे।

5

ओबीजेसी कुछ भी नहीं बचाता है।

इस ओबीजेसी कोड के लिए, यह दुर्घटनाग्रस्त हो गया क्योंकि मूल वर्ग बाल वर्ग से इवर तक पहुंचने का प्रयास कर रहा है। अगर स्विफ्ट नियम का उपयोग किया जाता है तो इसका पता लगाया जा सकता है/इससे बचें। अर्थात क्या मुद्दों स्विफ्ट इस लागू करके रोकने के लिए कोशिश कर रहा है इससे पहले कि [super init]

@interface Parent : NSObject 

@property (readonly) int value; 

@end 

@implementation Parent 

- (id)init { 
    self = [super init]; 
    if (self) { 
     NSLog(@"%d", self.value); // call a method, which can be overrided by child class 
    } 
    return self; 
} 

- (int)value { 
    return 42; 
} 

@end 

@interface Child : Parent 

@end 

@implementation Child { 
    int *_valuePtr; 
} 

- (id)init { 
    self = [super init]; // call self.value 
    if (self) { 
     // to avoid crash, move this line before [super init], but it may have other undesired effect. e.g. when [super init] return another instance 
     _valuePtr = calloc(sizeof(int), 1); 
    } 
    return self; 
} 

- (void)dealloc { 
    free(_valuePtr); 
} 

- (int)value { 
    return *_valuePtr; 
} 

- (void)setValue:(int)value { 
    *_valuePtr = value; 
} 

@end 
+0

धन्यवाद ब्रायन। आप उदाहरण में केवल int की बजाय int में पॉइंटर का उपयोग करने का निर्णय क्यों लेते हैं? – Boon

+1

@ बून वह एक सूचक का उपयोग कर रहा है क्योंकि यह इसे दुर्घटनाग्रस्त करने का एक आसान तरीका है। जब 'सुपर' के प्रारंभकर्ता '-value' को कॉल करते हैं, तो सबक्लास कार्यान्वयन का उपयोग किया जाता है। हालांकि, उपclass प्रारंभ करना समाप्त नहीं हुआ है, और इसलिए '_valuePtr'' NULL' है, और 'NULL' पॉइंटर को संदर्भित करने से आपके ऐप को क्रैश हो जाता है। दूसरे शब्दों में, उप-वर्ग का '-value' का कार्यान्वयन मानता है कि ऑब्जेक्ट पूरी तरह से प्रारंभ होने पर ऑब्जेक्ट को कभी भी लागू किया जाएगा। यह उद्देश्य-सी में एक दोषपूर्ण धारणा है, और जहां समस्या निहित है। –

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