मैं स्विफ्ट में UIViewController पर डिफ़ॉल्ट सुपर.इन () क्यों नहीं कह सकता हूं?


84

मैं UIViewControllerस्टोरीबोर्ड से उपयोग नहीं कर रहा हूं और मैं एक कस्टम initफ़ंक्शन करना चाहता हूं जहां मैं NSManagedObjectIDकिसी वस्तु में गुजरता हूं । मैं सिर्फ कॉल करना चाहता हूं जैसे कि super.init()मेरा उद्देश्य ऑब्जेक्टिव-सी में है। इस कदर:

init(objectId: NSManagedObjectID) {
    super.init()
}

लेकिन मुझे निम्नलिखित संकलक त्रुटि मिलती है:

सुपरक्लास UIViewController के नामित प्रारंभकर्ता को कॉल करना चाहिए

क्या मैं अब ऐसा नहीं कर सकता?

जवाबों:


119

के लिए नामित आरंभीकरण UIViewControllerहै initWithNibName:bundle:। आपको इसके बजाय कॉल करना चाहिए।

Http://www.bignerdranch.com/blog/real-iphone-crap-2-initwithnibnamebundle-is-the-designated-initializer-of-uiviewcontroller/ देखें

यदि आपके पास एक नीब नहीं है, nilतो निबनेम (बंडल वैकल्पिक भी है) के लिए पास करें। तब आप कस्टम दृश्य को निर्माण कर सकते हैं loadViewया self.viewमें viewDidLoad, जैसे कि आप उपयोग करते हैं, में सब-कुछ जोड़कर ।


4
तो यह वर्तमान में मेरे लिए एक UIViewController उपवर्ग में एक कस्टम init विधि बनाने के लिए असंभव है जो एक नीब से नहीं है?
सरूपर्तेर्थ

1
आह, धन्यवाद !! मैं निब नाम के लिए "" में गुजर रहा था।
सररूपर्ट आठ

2
ओह, थोड़ी खुदाई के बाद, यह प्रोटोकॉल initWithCoder:से निकलता है NSCoding... मैं अभी भी यह पता नहीं लगा सकता कि एक UIViewController उदाहरण को शुरू करने में इसकी भूमिका क्या है, चाहे वह UIViewController का "नामित" इनिशलाइज़र हो या इसके किसी सुपरक्लास का .. ।
निकोलस मिआरी

6
धन्यवाद! क्विक कॉपी / पेस्ट के लिए बस अपने letगुणों को सेट करने के बाद इसे कॉल करें , यदि कोई हो super.init(nibName: nil, bundle: nil):।
फेरन मायलिनच

3
जब आप राज्य बहाली करने की आवश्यकता होती है, तो Init with coder का उपयोग किया जाता है। जब आप राज्य पुनर्स्थापना कार्यक्षमता का उपयोग करके व्यूकंट्रोलर की स्थिति को सहेजते हैं, तो कोडर आपके द्वारा सहेजे गए मानों को वापस लौटा देगा जब राज्य सहेजा गया था। जब आप एप्लिकेशन को बंद करते हैं, तब से आप व्यू कंट्रोलर को उसकी अंतिम प्रारंभिक स्थिति में पुन: बना सकते हैं। तो उपयोगकर्ता के लिए जहां वे से दूर छोड़ दिया
Esko918

44

एक और अच्छा उपाय यह है कि आप अपने नए आरंइज़र को इनिशियलाइज़र के रूप में घोषित करें convenience:

convenience init( objectId : NSManagedObjectID ) {
    self.init()

    // ... store or user your objectId
}

यदि आप अपने उपवर्ग में कोई निर्दिष्ट प्रारंभकर्ता घोषित नहीं करते हैं, तो वे स्वचालित रूप से विरासत में प्राप्त होते हैं और आप self.init()अपनी सुविधा के आरंभक के भीतर उपयोग करने में सक्षम होते हैं ।

UIViewController के मामले में डिफ़ॉल्ट इनिट विधि दोनों तर्कों के init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)साथ कॉल करेगी nil(UIViewController पर कमांड-क्लिक आपको वह जानकारी देगा)।

टीएल; टीआर : यदि आप प्रोग्राम के साथ काम करना पसंद करते हैं तो UIViewControllerयहां एक पूर्ण कार्य उदाहरण है जो एक कस्टम तर्क के साथ एक नया इनिशलाइज़र जोड़ता है:

class MyCustomViewController: UIViewController {
    var myString: String = ""

    convenience init( myString: String ) {
        self.init()

        self.myString = myString
    }
}

यह एक और अधिक सुरुचिपूर्ण समाधान है और किसी भी सामान्य मामले में काम करता है
साइप्रियन

2
मैंने इसे एक विस्तार में करने की कोशिश की, और इसने खुद को फिर से बुलाया।
डेनियल आयटेकिन

12
इस उत्तर के लिए "चाल" वह यह है कि myStringकरने के लिए सेट कर दिया जाता ""है ताकि initआवश्यकता नहीं है। यदि आप एक प्रारंभिक मूल्य का उपयोग नहीं करना चाहते हैं, तो यह समाधान अलग हो जाता है, और उस स्थिति में आपको उपयोग करने की आवश्यकता हैself.init(nibName: nil, bundle:nil)
Dan Rosenstark

2
@Yar या आप कर myStringसंपत्ति एक वैकल्पिक
क्लास

1
@Klaas हाँ: मेरा मुद्दा यह है कि मैं केवल शुरुआती विकल्प का उपयोग कर रहा था वैकल्पिक से बचने और संकलन करने के लिए अपना कोड प्राप्त करने के लिए।
डैन रोसेनस्टार्क


15

अद्यतन: लिंक जोड़ें

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init

IOS के लिए प्रलेखन के अनुसार, UIViewController के लिए निर्दिष्ट इनिशियलाइज़र है initWithNibName: bundle:

यदि आप UIViewController को उप-वर्ग करते हैं, तो आपको इस पद्धति के सुपर कार्यान्वयन को कॉल करना होगा, भले ही आप NIB का उपयोग न कर रहे हों।

आप इसे निम्नानुसार कर सकते हैं:

init(objectId : NSManagedObjectID) {

    super.init(nibName: (xib's name or nil'), bundle: nil)

   // other code...
}

या

एक सुविधा इनिशियलाइज़र के रूप में एक नया इनिशलाइज़र घोषित करें:

 convenience init( objectId : NSManagedObjectID ) {

    self.init()

     // other code...

}


1
आपको इसे रद्दीकरण के रूप में छोड़ने के बजाय, रोपण के लिए मूल से जोड़ना चाहिए।
नाथन तुग्गी

मैंने @NcNc के समान प्रक्रिया का उपयोग किया। इसने मेरे लिए काम किया। यहाँ लिंक है
अनिल गुप्ता

@NathanTuggy नहीं, उसे नहीं करना चाहिए। लिंक्स में किसी दिन समाप्त या स्थानांतरित करने की सुविधा है। वह एक सूचना के बजाय 404 त्रुटि देखना चाहता है जिसे वह खोज रहा है?
mykolaj

1
@mykolaj: जानकारी यहाँ पहले से ही है, इस उत्तर में। (अन्यथा मैं लिंक-ओनली उत्तर के रूप में डिलीट करने के लिए झंडी दिखा रहा होता।) लेकिन एट्रिब्यूशन भी महत्वपूर्ण है ताकि जो कोई भी इसे पढ़ता है वह यह पता लगा सके कि यह कहां से आया है और उन्हें क्रेडिट करता है। एक स्क्रीनशॉट उसके लिए काम नहीं करता है, लेकिन एक लिंक करता है। यदि कोई लिंक घूमता है, तो यह दुर्भाग्यपूर्ण है, लेकिन आप संभवतः मुझे यह नहीं बता सकते हैं कि किसी भी तरह के क्रेडिट को कभी नहीं देने से भी बदतर स्थिति है। आपत्तियों एसओ के लिए लिंक-केवल जवाब कड़ी करने के लिए कर रहे हैं केवल जवाब। लिंक से नहीं। लिंक और जानकारी भी वांछित सूत्रीकरण है।
नाथन तुग्गी 20

@NathanTuggy मैंने अभी लिंक जोड़ा है। आपकी याद दिलाने के लिए धन्यवाद
NcNc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.