Swift:在运行时在非可选中检测到意外的 nil 值:强制转换为可选失败

Posted

技术标签:

【中文标题】Swift:在运行时在非可选中检测到意外的 nil 值:强制转换为可选失败【英文标题】:Swift: detecting an unexpected nil value in a non-optional at runtime: casting as optional fails 【发布时间】:2015-03-13 11:29:14 【问题描述】:

我有一个 UITableViewController 通过 NSFetchedResultsController 从 Core Data 加载其条目。像这样:

let historyItem = fetchedResults.objectAtIndexPath(indexPath) as HistoryItem

historyItem 有一个 title 属性定义如下:

@NSManaged var title: String

但不知何故,在某些条目中,核心数据的 title 值为 nil,这会导致 EXC_BAD_ACCESS,因为 title 不是 String?。这个问题已经在Check if property is set in Core Data? 得到了解决,那里的高票回答暗示了这样的事情:

    if let possibleTitle = historyItem.title as String? 
        NSLog("possibleTitle was set OK")
     else 
        NSLog("possibleTitle was nil")
    

但我刚刚尝试过,它仍然给了我 EXC_BAD_ACCESS:

同样的问题和解决方案也在 Swift - casting a nil core data string as an optional value 和我之前重复的问题Swift: handling an unexpected nil value, when variable is not optional 但这对我不起作用。我正在使用 Xcode 6.2 和 ios8。

请问我是不是误会了什么?这种方法应该奏效吗?

【问题讨论】:

这很有趣。我可以确认***.com/a/25664102/1187415 中提出的as String? 解决方案不再适用于 Xcode 6.2(在 iOS 8 模拟器中测试)。将属性类型更改为可选(***.com/a/25664102/1187415 中的“旧答案”)仍然有效。 这也在开发者论坛中进行了讨论:devforums.apple.com/message/995243#995243、devforums.apple.com/message/1110385#1110385,建议提交错误报告。 item.valueForKey("title") as String? ***.com/a/27412036/1187415 中的提议也可以。 啊!谢谢你,@martin-r!我试过item.valueForKey("title") as String?,这对我有用。但没有其他任何事情发生。如果你想提出这个作为答案,我很乐意打勾。谢谢! 解决方案“作为字符串?”每次都不起作用。对于 CoreData 中的 NSDate 非可选 nil ,仅当我之前将其登录到 printf 时才有效。这根本没有意义。 【参考方案1】:

如果核心数据可以为标题返回 nil 值,我认为您应该将标题设为可选

@NSManaged var title: String?

并在没有演员表的情况下对其进行测试

if let possibleTitle = historyItem.title
    NSLog("possibleTitle was set OK")
 else 
    NSLog("possibleTitle was nil")

【讨论】:

同意,Xcode 生成的类在 Swift 中是危险的,因为即使生成的属性不是可选的,Core Data 也可以返回 nil。 同意汤姆的观点。建议根据数据模型中的“可选”设置更新生成的 Swift 类。 我可能会更进一步说它们在 Swift 中都应该是可选的,因为在您保存更改之前,Core Data 不会强制执行有关必需属性值的规则。仍然有一个窗口值可以合法地为零。 我们是否也应该在数据模型文件中选中“可选”复选框? @Ben 仅当它应该是可选的。我不知道这是否是最好的方法,但如果该属性不应该是可选的,我给它以 Swift 结尾的!,所以如果它是 nil 是一个错误,我仍然可以检查它是否是 nil。

以上是关于Swift:在运行时在非可选中检测到意外的 nil 值:强制转换为可选失败的主要内容,如果未能解决你的问题,请参考以下文章

“致命错误:在 Swift ios 中使用 vImageBuffer_initWithCGImage 时在展开可选值时意外发现 nil”

防止 Obj-C 代码将 `nil` 传递给具有非可选参数的 Swift 方法

检查 nil 的非可选值

swift - bgMusic - 致命错误:在展开可选值时意外发现 nil

Swift 3 更新中的错误 - 在展开可选值时意外发现 nil

Swift transitionCoordinator() 意外发现 nil 错误