A classe 'ViewController' não possui inicializadores no swift

122

Recebendo a reclamação do compilador ao fazer isso

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) {
    }
}

No entanto, se eu apenas adicionar ? no final do AppDelegate, como abaixo, e o erro desapareceu.

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) {
    }
}

Não vejo optionalpalavras-chave relevantes para esse erro, a menos que esteja errado.

tranvutuan
fonte

Respostas:

238

O erro pode ser aprimorado, mas o problema com sua primeira versão é que você tem uma variável de membro delegate, que não possui um valor padrão. Todas as variáveis ​​no Swift devem sempre ter um valor. Isso significa que você precisa configurá-lo em um inicializador que não possui ou pode fornecer um valor padrão em linha.

Quando você o torna opcional, permite que seja nilpor padrão, removendo a necessidade de atribuir explicitamente um valor ou inicializá-lo.

drewag
fonte
45

A linguagem de programação Swift declara:

Classes e estruturas devem definir todas as suas propriedades armazenadas para um valor inicial apropriado no momento em que uma instância dessa classe ou estrutura é criada. As propriedades armazenadas não podem ser deixadas em um estado indeterminado.

Você pode definir um valor inicial para uma propriedade armazenada em um inicializador ou atribuir um valor de propriedade padrão como parte da definição da propriedade.

Portanto, você pode escrever:

class myClass {

    var delegate: AppDelegate //non-optional variable

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

}

Ou:

class myClass {

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

    init() {
        println("Hello")
    }

}

Ou:

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
    }

}

Mas você não pode escrever o seguinte:

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
    }

}
Imanou Petit
fonte
22

Às vezes, esse erro também aparece quando você tem um var ou um let que não foi inicializado.

Por exemplo

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

Dependendo do que sua variável deve fazer, você pode definir esse tipo de var como opcional ou inicializá-lo com um valor como o seguinte

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
}
Oliver S
fonte
então qual é a solução para isso?
precisa saber é o seguinte
eles podem ser iniciados em uma função init?
precisa saber é o seguinte
13

Esse problema geralmente aparece quando uma de suas variáveis ​​não tem valor ou quando você esquece de adicionar "!" para forçar essa variável a armazenar nada até que seja definida.

No seu caso, o problema está aqui:

var delegate: AppDelegate

Deve ser definido como var delegate: AppDelegate!opcional, que armazena nada e não desembrulha a variável até que o valor seja usado.

É triste que o Xcode destaque toda a classe como um erro, em vez de destacar a linha de código específica que a causou, por isso leva um tempo para descobrir isso.

Ivan V
fonte
Isso elimina a mensagem de erro para mim no caso de um IBOutlet, mas não no caso de variáveis ​​padrão.
amigos estão dizendo sobre tim
Isso resolve meu problema. Quando tentei fazer isso: var fetchedResultsController: NSFetchedResultsController Recebi o erro de compilação. Adicionando "!" o erro foi eliminado, como var fetchedResultsController: NSFetchedResultsController!
Jervisbay
obrigado por ans! Isso é útil para mim, eu apenas sabia "?" para valor opcional, mas "!" Eu não sabia antes. Eu coloco "!" assim: var time: NSTimer!
AmyNguyen #
10

se você perdeu um "!" no seu código, como este código abaixo, você também receberá esse erro.

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)
    }

}
saneryee
fonte
3

Substitua var appDelegate : AppDelegate?por let appDelegate = UIApplication.sharedApplication().delegateconforme indicado na segunda linha comentada viewDidLoad().

A palavra-chave "opcional" refere-se exatamente ao uso de ?, consulte isso para obter mais detalhes.

user2118161
fonte
1

Eu uso o Xcode 7 e o Swift 2. Por último, eu fiz:

classe ViewController: UIViewController {var time: NSTimer // erro isso aqui}

Então eu corrijo: class 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)
}

}

AmyNguyen
fonte
A clareza não está totalmente presente na sua resposta, mas esse foi o meu problema; Não especifiquei a opcionalidade de um membro var (forçado / opcional); depois que fiz e ajustei o código mais tarde, o ViewController não se queixou mais de não ter um inicializador.
James Perih
0

Para mim foi uma declaração incompleta. Por exemplo:

var isInverted: Bool

Em vez da maneira correta:

var isInverted: Bool = false
Alessandro Mattiuzzi
fonte