'ViewController'类没有快速初始化方法


122

当我这样做时,从编译器得到投诉

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除非我错了,否则我看不到与此错误相关的关键字。

Answers:


238

该错误可以得到改善,但是第一个版本的问题是您有一个成员变量,该成员变量delegate没有默认值。Swift中的所有变量必须始终具有一个值。这意味着您必须在没有的初始化程序中进行设置,也可以在线提供默认值。

当您将其设为可选时,nil默认情况下允许它为默认值,而无需显式为其提供值或对其进行初始化。


45

Swift编程语言指出:

类和结构必须在创建该类或结构的实例时将其所有存储的属性设置为适当的初始值。存储的属性不能处于不确定状态。

您可以在初始化程序中为存储的属性设置初始值,或者通过将默认属性值分配为属性定义的一部分来设置初始值。

因此,您可以编写:

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或let的情况下,也会出现此错误。

例如

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

根据变量的用途,您可以将该var类型设置为可选类型,或者使用如下所示的值对其进行初始化

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

当您的变量之一没有值或忘记添加“!”时,通常会出现此问题。强制此变量存储nil直到被设置。

您的问题在这里:

var delegate: AppDelegate

应该将其定义为var delegate: AppDelegate!使其成为可选的存储nil,并且在使用该值之前不要解开该变量。

令人遗憾的是,Xcode将整个类突出显示为一个错误,而不是突出显示导致该类的特定代码行,因此花点时间才能弄清楚。


对于IBOutlet,这确实为我消除了错误消息,但对于标准变量,却没有。
Tim Vermeulen

这解决了我的问题。当我尝试执行此操作时:var fetchedResultsController:NSFetchedResultsController我收到了编译错误。通过添加 ”!” 错误消失了,就像var fetchedResultsController:NSFetchedResultsController一样!
Jervisbay '16

感谢您的回答!这对我来说很痛苦,我才知道“?” 为可选值,但为“!” 我以前不知道。我设置 ”!” 像这样:var time:NSTimer!
AmyNguyen '16

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和Swift2。最后,我做了:

类ViewController:UIViewController {var time:NSTimer //此处有误}

然后,我修复:类ViewController: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)
}

}


您的答案并不十分清楚,但这是我的问题。我没有指定成员var的可选性(强制/可选);一旦完成,然后调整了代码,ViewController就不再抱怨没有初始化程序。
James Perih

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.