126

Getting the complaint from the compiler when I am doing this

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

However, if I just add ? at the end of AppDelegate like below and the error is gone.

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

I don't see optional keyword relevant to this error unless I am wrong.

Cœur
  • 37,241
  • 25
  • 195
  • 267
tranvutuan
  • 6,089
  • 8
  • 47
  • 83

8 Answers8

245

The error could be improved, but the problem with your first version is you have a member variable, delegate, that does not have a default value. All variables in Swift must always have a value. That means that you have to set it up in an initializer which you do not have or you could provide it a default value in-line.

When you make it optional, you allow it to be nil by default, removing the need to explicitly give it a value or initialize it.

drewag
  • 93,393
  • 28
  • 139
  • 128
48

The Swift Programming Language states:

Classes and structures must set all of their stored properties to an appropriate initial value by the time an instance of that class or structure is created. Stored properties cannot be left in an indeterminate state.

You can set an initial value for a stored property within an initializer, or by assigning a default property value as part of the property’s definition.

Therefore, you can write:

class myClass {

    var delegate: AppDelegate //non-optional variable

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

}

Or:

class myClass {

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

    init() {
        println("Hello")
    }

}

Or:

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
    }

}

But you can't write the following:

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
  • 89,880
  • 29
  • 256
  • 218
25

Sometimes this error also appears when you have a var or a let that hasn't been intialized.

For example

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

Depending on what your variable is supposed to do you might either set that var type as an optional or initialize it with a value like the following

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
  • 993
  • 1
  • 9
  • 11
14

This issue usually appears when one of your variables has no value or when you forget to add "!" to force this variable to store nil until it is set.

In your case the problem is here:

var delegate: AppDelegate

It should be defined as var delegate: AppDelegate! to make it an optional that stores nil and do not unwrap the variable until the value is used.

It is sad that Xcode highlights the whole class as an error instead of highlighting the particular line of code that caused it, so it takes a while to figure it out.

Ivan V
  • 3,024
  • 4
  • 26
  • 36
  • This does get rid of the error message for me in case of an IBOutlet, but not in case of a standard variables. – Tim Vermeulen Dec 24 '15 at 21:52
  • This solves my problem. When I tried to do this: var fetchedResultsController: NSFetchedResultsController I got the compile error. By adding "!" the error went away, like so var fetchedResultsController: NSFetchedResultsController! – Jervisbay Mar 05 '16 at 23:23
  • thanks for ur ans! This is helful for me, I just have known "?" to optional value but "!" I have not known before. I set "!" like that: var time: NSTimer! – AmyNguyen Apr 01 '16 at 04:14
10

if you lost a "!" in your code ,like this code below, you'll also get this 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
  • 3,239
  • 31
  • 22
3

Replace var appDelegate : AppDelegate? with let appDelegate = UIApplication.sharedApplication().delegate as hinted on the second commented line in viewDidLoad().

The keyword "optional" refers exactly to the use of ?, see this for more details.

1

I use Xcode 7 and Swift 2. Last, I had made:

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

Then I fix: 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
  • 437
  • 6
  • 10
  • The clarity isn't quite all there in your answer, but this was my problem; I didn't specify a member var's optionality (forced/optional); once I did, and adjusted code later, ViewController no longer complained about not having an initializer. – James Perih Jun 17 '16 at 20:13
0

For me was a declaration incomplete. For example:

var isInverted: Bool

Instead the correct way:

var isInverted: Bool = false
Alessandro Mattiuzzi
  • 2,309
  • 2
  • 18
  • 24