La clase 'ViewController' no tiene inicializadores en swift

123

Obteniendo la queja del compilador cuando estoy haciendo esto

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

Sin embargo, si solo agrego ? al final de AppDelegate como a continuación y el error se ha ido.

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 veo optionalpalabras clave relevantes para este error a menos que me equivoque.

tranvutuan
fuente

Respuestas:

239

El error podría mejorarse, pero el problema con su primera versión es que tiene una variable miembro delegate, que no tiene un valor predeterminado. Todas las variables en Swift siempre deben tener un valor. Eso significa que debe configurarlo en un inicializador que no tiene o puede proporcionarle un valor predeterminado en línea.

Cuando lo hace opcional, permite que sea nilpor defecto, eliminando la necesidad de darle un valor explícito o inicializarlo.

Drewag
fuente
45

El lenguaje de programación Swift establece:

Las clases y estructuras deben establecer todas sus propiedades almacenadas en un valor inicial apropiado para el momento en que se crea una instancia de esa clase o estructura. Las propiedades almacenadas no se pueden dejar en un estado indeterminado.

Puede establecer un valor inicial para una propiedad almacenada dentro de un inicializador, o asignando un valor de propiedad predeterminado como parte de la definición de la propiedad.

Por lo tanto, puedes escribir:

class myClass {

    var delegate: AppDelegate //non-optional variable

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

}

O:

class myClass {

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

    init() {
        println("Hello")
    }

}

O:

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
    }

}

Pero no puedes escribir lo siguiente:

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
fuente
22

A veces, este error también aparece cuando tienes una var o let que no se ha inicializado.

Por ejemplo

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

Dependiendo de lo que se supone que debe hacer su variable, puede establecer ese tipo de var como opcional o inicializarlo con un valor como el siguiente

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
fuente
Entonces, ¿cuál es la solución a esto?
Martian2049
¿se pueden iniciar en una función init en su lugar?
Martian2049
13

Este problema generalmente aparece cuando una de sus variables no tiene valor o cuando olvida agregar "!" para forzar a esta variable a almacenar nulo hasta que se establezca.

En su caso, el problema está aquí:

var delegate: AppDelegate

Debe definirse como var delegate: AppDelegate!una opción que almacene nulo y no desenvuelva la variable hasta que se use el valor.

Es triste que Xcode resalte a toda la clase como un error en lugar de resaltar la línea particular de código que lo causó, por lo que lleva un tiempo resolverlo.

Ivan V
fuente
Esto elimina el mensaje de error para mí en el caso de un IBOutlet, pero no en el caso de las variables estándar.
Tim Vermeulen
Esto resuelve mi problema. Cuando intenté hacer esto: var fetchedResultsController: NSFetchedResultsController recibí el error de compilación. Añadiendo "!" el error desapareció, como así var fetchedResultsController: NSFetchedResultsController!
Jervisbay
gracias por tu ans! Esto es útil para mí, acabo de saber "?" a valor opcional pero "!" No lo he sabido antes. Lo puse "!" así: var time: NSTimer!
AmyNguyen
10

si perdiste un "!" en su código, como este código a continuación, también obtendrá este error.

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
fuente
3

Reemplace var appDelegate : AppDelegate?con lo let appDelegate = UIApplication.sharedApplication().delegateque se indica en la segunda línea comentada viewDidLoad().

La palabra clave "opcional" se refiere exactamente al uso de ?, consulte esto para obtener más detalles.

usuario2118161
fuente
1

Uso Xcode 7 y Swift 2. Por último, hice:

class ViewController: UIViewController {var time: NSTimer // error this here}

Luego arreglo: 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
fuente
La claridad no está del todo en su respuesta, pero este fue mi problema; No especifiqué la opcionalidad de un miembro var (forzado / opcional); una vez que lo hice, y ajusté el código más tarde, ViewController ya no se quejaba de no tener un inicializador.
James Perih
0

Para mí fue una declaración incompleta. Por ejemplo:

var isInverted: Bool

En cambio, la forma correcta:

var isInverted: Bool = false
Alessandro Mattiuzzi
fuente