出乎意料地发现零

时间:2015-03-24 20:25:46

标签: ios xcode swift core-data updating

我正在为CoreData进行更新,我需要加载数据以便编辑到textfields。在viewDidLoad中的AddViewController我有

if let myData = data {

            knihaTextField.text = data.valueForKey("kniha") as? String
            autorTextField.text = data.valueForKey("autor") as? String
            rokTextField.text = data.valueForKey("rok") as? String
            vydavatelstvoTextField.text = data.valueForKey("vydavatelstvo") as? String
            stranyTextField.text = data.valueForKey("strany") as? String

        }

在knihaTextField.text = data.valueForKey(“kniha”)中?字符串我收到错误

  

致命错误:在解包可选值时意外发现nil

完整代码:

http://pastebin.com/yF53nbSE

我正在从DetailView到PridatView做segue - 完整代码:

http://pastebin.com/BeG4eZHX

4 个答案:

答案 0 :(得分:1)

if let如何在这里工作存在误解。

myData声明后使用data,而不是if let

if let myData = data {
    knihaTextField.text = myData.valueForKey("kniha") as? String
}

答案 1 :(得分:1)

您不知道某些参数是否为零。您应该为所有参数执行可选绑定(如果您始终需要它们全部设置)。这就是你如何从Swift 1.2(Xcode 6.3 Beta)进行多次展开:

编辑:您可以使用速记语法来访问值:

if let myData = data as? NSDictionary {
    if let kniha = myData["kniha"] as? String, autor = myData["autor"] as? String, 
       rok = myData["rok"] as? String, vydavatelstvo = myData["vydavatelstvo"] as? String, 
       strany = myData["strany"] as? String {
           knihaTextField.text = kniha 
           autorTextField.text = autor
           rokTextField.text = rok
           vydavatelstvoTextField.text = vydavatelstvo
           stranyTextField.text = strany
    }
}

答案 2 :(得分:1)

knihaTextField可能是nil。如果您使用的是Interface Builder,则表示尚未连接它。

看到你的代码后 - 问题在于文本字段在单元格内部。创建单元格时,您将其文本字段保存为变量。但是,viewDidLoad通常是控制器中的第一个调用,在表视图委托之前肯定会调用,因此所有文本字段都将为nil

我的建议是忘记viewDidLoad并删除所有UITextField个变量。相反,你应该:

if (indexPath.row == 0) {
    cell!.configure("Názov knihy", delegate:self)
    cell!.textField.text = data?.valueForKey("kniha") as? String
}
else if (indexPath.row == 1) {
    cell!.configure("Meno autora", delegate:self)
    cell!.textField.text = data?.valueForKey("autor") as? String
}

你也可以像这样简化代码

let titles = ["Názov knihy", "Meno autora"] //add the other titles here
let propertyKeys = ["kniha", "autor"]   //add the other keys here

cell!.configure(titles[indexPath.row], delegate:self)
cell!.textField.text = data?.valueForKey(propertyKeys[indexPath.row]) as? String

如果你想在几个文本字段之间分散注意力,这是使用UIView.tag是一个简单(不是最好的)解决方案的情况之一。

cell!.textField.tag = indexPath.row

您的代码中还有其他问题。通常,表格单元格会动态发布并重新分配,因此您无法以这种方式保留对文本字段的引用。

可能最好的架构是:

  1. 为每个String值设置实例变量。
  2. viewDidLoad中设置data的变量值。
  3. cellForRow中仅使用实例变量,请勿使用data
  4. 设置UITextFieldDelegate,将文本值保存回实例变量(使用tag来消除文本字段)。
  5. saveTapped中使用实例变量写回data,不要使用textFields。
  6. 说实话,如果您删除UITableView并将其替换为UIScrollView,整个用例会变得更容易。在Interface Builder中设计屏幕会使它变得非常快,并且会变得更容易,因为您不会遇到细胞重用问题。此外,如果连接正确,则viewDidLoad中的所有文本字段都已为非零。

答案 3 :(得分:-1)

伙计们,谢谢你的帮助。但我和朋友解决了。并决定它需要在viewDidAppear

 override public func viewDidAppear(animated: Bool) {
        if let myData = data {
            knihaTextField.text = myData.valueForKey("kniha") as? String
            autorTextField.text = myData.valueForKey("autor") as? String
            rokTextField.text = myData.valueForKey("rok") as? String
            vydavatelstvoTextField.text = myData.valueForKey("vydavatelstvo") as? String
            stranyTextField.text = myData.valueForKey("strany") as? String
        } 
    }