意外发现nil
Unexpectly found nil
我正在更新 CoreData,我需要加载数据以编辑到文本字段。在 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")中作为?字符串我收到错误
fatal error: unexpectedly found nil while unwrapping an Optional value
完整代码:
我正在做从 DetailView 到 PridatView 的 segue - 完整代码:
这里对 if let
的工作原理存在误解。
在 if let
语句之后使用 myData
,而不是 data
。
if let myData = data {
knihaTextField.text = myData.valueForKey("kniha") as? String
}
你不知道你的某些参数是否不为零。你应该为你的所有参数做一个可选的绑定(以防你总是需要它们全部设置)。这就是从 Swift 1.2 (Xcode 6.3 Beta):
开始进行多重展开的方式
编辑:您可以使用shorthand语法访问值:
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
}
}
knihaTextField
大概是nil
。如果您使用的是 Interface Builder,那么您还没有连接它。
看到您的代码后 - 问题在于文本字段位于单元格内。创建单元格时,您将它们的文本字段保存到变量中。但是,viewDidLoad
通常是控制器中的第一个调用,肯定在 table 视图委托之前调用,因此您的所有文本字段都将是 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
您的代码中还有其他问题。通常,table 单元格是动态释放和重新分配的,因此您不能以这种方式保留对文本字段的引用。
最好的架构可能是:
- 每个
String
值都有实例变量。
- 在
viewDidLoad
中设置来自 data
的变量值。
- 在
cellForRow
中只使用实例变量,不要使用data
。
- 有一个
UITextFieldDelegate
可以将文本值保存回您的实例变量(使用 tag
区分文本字段)。
- 在
saveTapped
中使用实例变量写回data
,不要使用textFields。
老实说,如果您删除 UITableView
并将其替换为 UIScrollView
,整个用例会变得更容易。在 Interface Builder 中设计屏幕会使它变得非常快并且会变得更容易,因为您不会遇到单元重用的问题。此外,如果连接正确,viewDidLoad
.
中的所有文本字段都已经非零
伙计们,谢谢你们的帮助。但是我和朋友一起解决了。并决定它需要在 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
}
}
我正在更新 CoreData,我需要加载数据以编辑到文本字段。在 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")中作为?字符串我收到错误
fatal error: unexpectedly found nil while unwrapping an Optional value
完整代码:
我正在做从 DetailView 到 PridatView 的 segue - 完整代码:
这里对 if let
的工作原理存在误解。
在 if let
语句之后使用 myData
,而不是 data
。
if let myData = data {
knihaTextField.text = myData.valueForKey("kniha") as? String
}
你不知道你的某些参数是否不为零。你应该为你的所有参数做一个可选的绑定(以防你总是需要它们全部设置)。这就是从 Swift 1.2 (Xcode 6.3 Beta):
开始进行多重展开的方式编辑:您可以使用shorthand语法访问值:
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
}
}
knihaTextField
大概是nil
。如果您使用的是 Interface Builder,那么您还没有连接它。
看到您的代码后 - 问题在于文本字段位于单元格内。创建单元格时,您将它们的文本字段保存到变量中。但是,viewDidLoad
通常是控制器中的第一个调用,肯定在 table 视图委托之前调用,因此您的所有文本字段都将是 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
您的代码中还有其他问题。通常,table 单元格是动态释放和重新分配的,因此您不能以这种方式保留对文本字段的引用。
最好的架构可能是:
- 每个
String
值都有实例变量。 - 在
viewDidLoad
中设置来自data
的变量值。 - 在
cellForRow
中只使用实例变量,不要使用data
。 - 有一个
UITextFieldDelegate
可以将文本值保存回您的实例变量(使用tag
区分文本字段)。 - 在
saveTapped
中使用实例变量写回data
,不要使用textFields。
老实说,如果您删除 UITableView
并将其替换为 UIScrollView
,整个用例会变得更容易。在 Interface Builder 中设计屏幕会使它变得非常快并且会变得更容易,因为您不会遇到单元重用的问题。此外,如果连接正确,viewDidLoad
.
伙计们,谢谢你们的帮助。但是我和朋友一起解决了。并决定它需要在 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
}
}