【问题标题】:Having trouble with a nil while unwrapping an Optional value在展开可选值时遇到 nil 问题
【发布时间】:2020-04-13 10:10:47
【问题描述】:

我正在尝试从 firebase 检索 postImageUrl,但由于某种原因,我在使用 postImageUrl 展开 nil 时收到错误消息。如何使此代码正常工作,以便我可以从 firebase 检索图像 url 而不会导致崩溃?

Code Screenshot

Firebase Database

【问题讨论】:

  • 我猜postURL 实际上是nil。您应该使用guard let ... else 来验证该值是否有效,而不是强制解包,而是使用选项
  • 在 Firebase 数据库中分享帖子的 sn-p,以便我们查看您尝试将哪些数据加载到 postImageUrl 中
  • 也许你只需要在第97行做let postImageUrl = dict["postImageUrl"] as! String
  • 我试过了,但它崩溃了。我得到同样的错误
  • 请内联发布您的代码,而不是截图。

标签: swift firebase


【解决方案1】:

一般来说,您应该避免使用! force-unwrap 运算符,除非您可以 100% 证明该值永远不会是 nil,这应该是极少数情况下(通常在加载包含在您应用程序的捆绑包)。这显然不是这里的情况,因为值 nil,所以你应该使用if letguard let 来解包值,处理它是nil 的情况,或者您可以使用?? 运算符提供默认值,如下所示:

doSomethingWith(foo ?? "this string gets passed if foo is nil")

根据您的Post 对象应该做什么,它也可能实际上适合包含imageURLnil 值。在这种情况下,您可能只想通过在其类型末尾添加 ? 来将其 imageURL 属性声明为可选:

struct Post: Codable {
    ...
    let imageURL: URL? // or String? if that's what it is
    ...
}

在这种情况下,您可以稍后解开 imageURL 属性,当需要使用它时。

【讨论】:

    【解决方案2】:

    最好的做法是通过安全地解包并提供默认值来处理可选项,以防出现 nil 或不执行可能导致应用程序崩溃的代码。

    此外,Firebase 快照功能非常强大,可让您轻松深入了解子节点。

    这里有一些显示这两种技术的更新代码。

    func gerAllFeedPosts() {
        REF_FEED.observeSingleEvent(of: .value, with: { snapshot in
            let allPosts = snapshot.children.allObjects as! [DataSnapshot]
            for postSnap in allPosts { //if there are no posts, no closure code will run
                let authorSnap = postSnap.childSnapshot(forPath: "author")
                let uid = authorSnap.childSnapshot(forPath: "uid").value as? String ?? "NO UID!"
                let username = authorSnap.childSnapshot(forPath: "username").value as? String ?? "NO USERNAME!"
    

    【讨论】:

      【解决方案3】:

      修改这行代码93:

      let author = dict!["author"] as? [String: AnyObject]
      

      【讨论】:

      • @GerardoLeon 这里的问题是,这是以不安全的方式展开可选的 - 如果 dict 为 nil,应用程序将崩溃。因此,安全地展开它是最佳实践和/或在这些情况下提供默认值是一个好主意。当前的快速代码也是[String: Any]。还有执行此功能的替代方法 - 请参阅我的答案。
      • @Jay firebase 字典实例始终存在 [String: AnyObject]。您需要检查 firebase 文档。
      • 大声笑。当您需要无类型对象的灵活性或使用返回无类型结果的桥接 Objective-C 方法和属性时,请使用 AnyObject。虽然它出现在有些过时的文档中,但 Playground 中的快速测试应该非常有启发性。试试这个let x: [String: AnyObject] = ["key": "value"] 然后试试这个let y: [String: Any] = ["key": "value"] 并查看结果。另请查看this answer 以获取其他信息。 AnyObject 没有错,只是“旧”。
      猜你喜欢
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多