0

Firstly, I'm very new to Swift, so keep that in mind before you berate my question for being an easy problem to solve.

I'm trying to use a button to send the contents of text field to a table. This bit of code defines the variable and you can see the sender:

import UIKit

var bookTitle:String!

class secondViewController: UIViewController {

@IBOutlet weak var titleField: UITextField!

@IBAction func addBook(sender: AnyObject) {
    bookTitle = (titleField.text)!
}

This is the code where I'm receiving the error message:

import UIKit

var cellContent = ["Book 1", "Book 2", "Book 3", "Book 4"]

class firstViewController: UIViewController, UITableViewDelegate {

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    cellContent.insert(bookTitle, atIndex: 0)
//THIS IS THE ERROR:  EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return cellContent.count
}

From searching online, I think the problem is that the variable "bookTitle" is nil, but I'm not sure how to fix that.

  • 1
    With `var bookTitle:String!` you've made your variable an *implicitly unwrapped optional* (this is what you want to search and read about). It means it must not be nil in any case. If you never actioned `addBook`, then `bookTitle` is nil, so the app crashes when you try to use it. – Eric Aya Apr 20 '16 at 21:22
  • 1
    [My answer here](http://stackoverflow.com/a/36360605/2976878) may be helpful in explaining how to properly deal with optionals. Essentially, you should only ever be using implicitly unwrapped optionals as a last resort. If you can make that variable non-optional with a default value, a lazy variable or a normal optional – you should do so. You should only ever be using IUOs if you know beyond doubt that it will *always* be non-nil after you initialise it and you never access it before initialising it. – Hamish Apr 20 '16 at 21:43

1 Answers1

1

It's because of your

var bookTitle:String!

Because you are accessing it before it was set. You can check that using the didSet.

var bookTitle: String! {
   didSet {
      print("did set called")
   }
}

You should use this declaration instead:

var bookTitle: String?

It's much safer because you have to unwrap your variable when accessing it. You should read the Swift documentation chapter about optional and explicit types.

For reference:

Because the value of an implicitly unwrapped optional is automatically unwrapped when you use it, there’s no need to use the ! operator to unwrap it. That said, if you try to use an implicitly unwrapped optional that has a value of nil, you’ll get a runtime error.

See: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/doc/uid/TP40014097-CH31-ID445

Chapter: Implicitly Unwrapped Optional Type