致命错误︰ 意外地发现了同时展开一个可选的值为零Swift

发布时间: 2017/3/5 20:39:27
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

所以我现在想转换到我用于表内容的数组存储在 NSUserdefault 中的 NSDictionary,但我遇到很多很多的错误,包括"致命错误︰ 意外地发现了同时展开一个可选的值为零",(目前一个) 我想问问什么最安全和正确的路径,将其转换。

这里是我的代码。

        let nsd:NSDictionary = NSUserDefaults.standardUserDefaults().valueForKey("storedPosts") as! NSDictionary
        for (postId, postInfo) in nsd{ //post id and the post
            let importedPost:Post = Post(postId: postId as! String, priorityLevel: postInfo.objectForKey("priorityLevel") as! String, status: postInfo.objectForKey("status") as! String, section: postInfo.objectForKey("section") as! String, userType: postInfo.objectForKey("userType") as! String, dataPosted: postInfo.objectForKey("dataPosted") as! String, lastUpdate: postInfo.objectForKey("lastUpdate") as! String, states: postInfo.objectForKey("states") as! String, personalizedToViewerData: postInfo.objectForKey("personalizedToViewerData") as! [String:Bool], content: postInfo.objectForKey("content") as! Dictionary<String, Any>)
        posts.append(importedPost)
}

任何建议将不胜感激

解决方法 1:

当你"力解"可选的 ! ,你告诉编译器"没关系我们可以总是打开因为肯定总是会有一个值"。

但如果实际上没有值,应用程序会崩溃...

所以你也要先安全地解开你件。

还有大量的技术,最简单的现在是 if let

与"如果让"你安全地打开一个值到一个新的常数,然后你可以使用这个新的常数,而不是任择。如果您需要检查类型或沮丧,你可以使用"条件转换"(真名是"可选绑定",我相信) 与 if let xxx = yyy as? zzz

让我们看看我们怎么能这样︰

if let nsd = NSUserDefaults.standardUserDefaults().valueForKey("storedPosts") as? NSDictionary {
    // use `nsd` here
}

让我们更进一步︰

if let nsd = NSUserDefaults.standardUserDefaults().valueForKey("storedPosts") as? NSDictionary {
    for (postId, postInfo) in nsd {
        if let id = postId as? String {

        }
    }
}

有用的但我们看到,使用"如果让"为每个值将导致厄运的"金字塔"......

为这一经典解决方案是使用相同的多个可选绑定"如果让":

if let nsd = NSUserDefaults.standardUserDefaults().valueForKey("storedPosts") as? NSDictionary {
    for (postId, postInfo) in nsd {
        if let id = postId as? String,
            priorityLevel = postInfo.objectForKey("priorityLevel") as? String,
            status = postInfo.objectForKey("status") as? String,
            section = postInfo.objectForKey("section") as? String {  // keep doing the same for all your values

            let importedPost = Post(postId: id, priorityLevel: priorityLevel, status: status, section: section, ...)  // etc

        }
    }
}

一个好的副作用是,你现在可以通过添加处理错误 else 分支到"如果让"需要的条件。

官方微信
官方QQ群
31647020