2016-04-20 25 views
0

首先,我對Swift非常陌生,所以在你解決我的問題之前記住Swift是一個容易解決的問題。Swift Variable Nil會導致致命錯誤:意外地發現零,同時展開一個可選值

我正在嘗試使用按鈕將文本字段的內容發送到表。這段代碼定義變量,你可以看到發件人:

import UIKit 

var bookTitle:String! 

class secondViewController: UIViewController { 

@IBOutlet weak var titleField: UITextField! 

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

這是我收到錯誤消息的代碼:

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 
} 

從網上搜索,我認爲這個問題是變量「bookTitle」是零,但我不知道如何解決這個問題。

+1

隨着'VAR BOOKTITLE:字符串'你做了你的變量的*隱含展開可選* (這是你想要搜索和閱讀的內容)。這意味着在任何情況下它都不能爲零。如果你從未使用過'addBook',那麼'bookTitle'就是零,所以當你嘗試使用它時,該應用會崩潰。 – Moritz

+1

[我的答案在這裏](http://stackoverflow.com/a/36360605/2976878)可能有助於解釋如何正確處理optionals。從本質上講,你應該只使用隱式解包選項作爲最後的手段。如果你可以用一個默認值,一個懶惰變量或一個普通的可選項來使這個變量非可選 - 你應該這樣做。如果你毫無疑問地知道它在初始化之後總是會非零,並且在初始化之前永遠不會訪問它,那麼你只應該使用IUO。 – Hamish

回答

1

這是因爲你的

var bookTitle:String! 

因爲你正在訪問它,它被設置之前。你可以使用didSet檢查。

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

你應該使用這個聲明來代替:

var bookTitle: String? 

這是安全得多,因爲你有訪問,當它解開您的變量。你應該閱讀關於可選和顯式類型的Swift文檔章節。

參考:

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.

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

章:無包裝隱可選類型

相關問題