क्लास 'व्यूकंट्रोलर' के पास स्विफ्ट में कोई इनिशियलाइज़र नहीं है


123

कंपाइलर से शिकायत मिलने पर जब मैं ऐसा कर रहा हूं

class ViewController: UIViewController {

    var delegate : AppDelegate
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.appDelegate = UIApplication.sharedApplication().delegate;

    }

    @IBAction func getData(sender : AnyObject) {

    }

    @IBAction func LogOut(sender : AnyObject) {
    }
}

हालाँकि, अगर मैं अभी जोड़ूँ ? नीचे की तरह AppDelegate के अंत में और त्रुटि दूर हो गई है।

class ViewController: UIViewController {

    var delegate : AppDelegate?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.appDelegate = UIApplication.sharedApplication().delegate;

    }

    @IBAction func getData(sender : AnyObject) {

    }

    @IBAction func LogOut(sender : AnyObject) {
    }
}

optionalजब तक मैं गलत नहीं हूं, मुझे इस त्रुटि के लिए प्रासंगिक कीवर्ड दिखाई नहीं देता है।

जवाबों:


239

त्रुटि में सुधार किया जा सकता है, लेकिन आपके पहले संस्करण के साथ समस्या यह है कि आपके पास एक सदस्य चर है, delegateजिसमें डिफ़ॉल्ट मान नहीं है। स्विफ्ट में सभी चर का हमेशा मान होना चाहिए। इसका मतलब है कि आपको इसे एक इनिशलाइज़र में सेट करना होगा जो आपके पास नहीं है या आप इसे इन-लाइन में डिफ़ॉल्ट मान प्रदान कर सकते हैं।

जब आप इसे वैकल्पिक बनाते हैं, तो आप इसे nilडिफ़ॉल्ट रूप से करने की अनुमति देते हैं, इसे स्पष्ट रूप से एक मूल्य देने या इसे शुरू करने की आवश्यकता को हटाते हैं।


45

स्विफ्ट प्रोग्रामिंग लैंग्वेज बताती है:

उस वर्ग या संरचना का निर्माण होने तक वर्गों और संरचनाओं को अपने सभी संग्रहीत गुणों को एक उचित प्रारंभिक मूल्य पर सेट करना होगा। एक अनिश्चित स्थिति में संग्रहीत संपत्तियों को नहीं छोड़ा जा सकता है।

आप किसी संग्रहित संपत्ति के लिए एक प्रारंभिक मूल्य के भीतर, या संपत्ति की परिभाषा के हिस्से के रूप में एक डिफ़ॉल्ट संपत्ति मूल्य निर्दिष्ट करके एक प्रारंभिक मूल्य निर्धारित कर सकते हैं।

इसलिए, आप लिख सकते हैं:

class myClass {

    var delegate: AppDelegate //non-optional variable

    init() {
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

या:

class myClass {

    var delegate = UIApplication.sharedApplication().delegate as AppDelegate //non-optional variable

    init() {
        println("Hello")
    }

}

या:

class myClass {

    var delegate : AppDelegate! //implicitly unwrapped optional variable set to nil when class is initialized

    init() {
        println("Hello")
    }

    func myMethod() {
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

लेकिन आप निम्नलिखित नहीं लिख सकते हैं:

class myClass {

    var delegate : AppDelegate //non-optional variable

    init() {
        println("Hello")
    }

    func myMethod() {
        //too late to assign delegate as an non-optional variable
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

22

कभी-कभी यह त्रुटि तब भी दिखाई देती है जब आपके पास एक var या ऐसा लेट होता है जिसे intialized नहीं किया जाता है।

उदाहरण के लिए

class ViewController: UIViewController {
    var x: Double
    // or
    var y: String
    // or
    let z: Int
}

इस बात पर निर्भर करता है कि आपका चर क्या करने वाला है या तो आप उस प्रकार को एक वैकल्पिक के रूप में सेट कर सकते हैं या इसे निम्न जैसे मान के साथ आरंभ कर सकते हैं

class ViewController: UIViewCOntroller {
    // Set an initial value for the variable
    var x: Double = 0
    // or an optional String
    var y: String?
    // or
    let z: Int = 2
}

तो इसका समाधान क्या है?
Martian2049

क्या इसके बदले उन्हें एक init फ़ंक्शन में सम्मिलित किया जा सकता है?
Martian2049

13

यह समस्या आमतौर पर तब दिखाई देती है जब आपके किसी चर का कोई मूल्य नहीं होता है या जब आप जोड़ना भूल जाते हैं "!" इस वैरिएबल को बल देने के लिए जब तक यह सेट न हो जाए।

आपके मामले में समस्या यहाँ है:

var delegate: AppDelegate

var delegate: AppDelegate!इसे एक वैकल्पिक विकल्प के रूप में परिभाषित किया जाना चाहिए जो शून्य को संग्रहीत करता है और जब तक कि मूल्य का उपयोग नहीं किया जाता है तब तक चर को खोलना नहीं है।

यह दुःखद है कि कोड की विशेष लाइन को उजागर करने के बजाय Xcode पूरी कक्षा को एक त्रुटि के रूप में उजागर करता है, इसलिए इसे पता लगाने में थोड़ा समय लगता है।


यह IBOutlet के मामले में मेरे लिए त्रुटि संदेश से छुटकारा दिलाता है, लेकिन एक मानक चर के मामले में नहीं।
टिम वर्म्यूलेन

इससे मेरी समस्या हल हो गई। जब मैंने ऐसा करने की कोशिश की: var fetchedResultsController: NSFetchedResultsController मुझे संकलन त्रुटि मिली। जोड़ कर "!" त्रुटि चली गई, जैसे कि var fetchedResultsController: NSFetchedResultsController!
जर्विस्बे

उर ans के लिए धन्यवाद! यह मेरे लिए उपयोगी है, मुझे अभी पता चला है "?" वैकल्पिक मूल्य पर ""! मुझे पहले पता नहीं है। मैं सेट करता हूं "!" उस तरह: var समय: NSTimer!
एमीग्युयेन

10

यदि आप एक "खो दिया है!" आपके कोड में, नीचे दिए गए कोड की तरह, आपको भी यह त्रुटि मिलेगी।

import UIKit

class MemeDetailViewController : UIViewController {

    @IBOutlet weak var memeImage: UIImageView!

    var meme:Meme! // lost"!"

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)
        self.memeImage!.image = meme.memedImage
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
    }

}

3

बदलें var appDelegate : AppDelegate?के साथ let appDelegate = UIApplication.sharedApplication().delegateके रूप में में दूसरा टिप्पणी की लाइन पर संकेत दियाviewDidLoad()

कीवर्ड "वैकल्पिक" का उपयोग करने के लिए बिल्कुल संदर्भित है ?, इसे अधिक विवरण के लिए देखें।


1

मैं Xcode 7 और स्विफ्ट 2 का उपयोग करता हूं। अंतिम, मैंने बनाया था:

वर्ग ViewController: UIViewController {var समय: NSTimer // यहाँ यह त्रुटि}

तब मैं ठीक करता हूं: वर्ग दृश्य नियंत्रक: UIViewController {

var time: NSTimer!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewWillAppear(animated: Bool) {
    //self.movetoHome()
    time = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(ViewController.movetoHome), userInfo: nil, repeats: false)
    //performSegueWithIdentifier("MoveToHome", sender: self)
    //presentViewController(<#T##viewControllerToPresent: UIViewController##UIViewController#>, animated: <#T##Bool#>, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
}

func movetoHome(){
    performSegueWithIdentifier("MoveToHome", sender: self)
}

}


स्पष्टता आपके उत्तर में बिलकुल नहीं है, लेकिन यह मेरी समस्या थी; मैंने सदस्य संस्करण की वैकल्पिकता (जबरन / वैकल्पिक) निर्दिष्ट नहीं की; एक बार जब मैंने किया, और बाद में कोड समायोजित किया, ViewController ने अब इनिशियलाइज़र नहीं होने के बारे में शिकायत नहीं की।
जेम्स पेरीह

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