【问题标题】:after update - Unexpectedly found nil while unwrapping an Optional value更新后 - 在展开可选值时意外发现 nil
【发布时间】:2018-07-28 21:32:39
【问题描述】:

更新项目后,出现此错误:

在展开可选值时意外发现 nil

class Search {
    private var _username: String!
    private var _userImg: String!
    private var _userKey: String!
    private var _userRef: DatabaseReference!

    var currentUser = KeychainWrapper.standard.string(forKey: "uid")

    var username: String {
        return _username <- error
    }

    var userImg: String {
        return _userImg
    }

    var userKey: String{
        return _userKey
    }

    init(username: String, userImg: String) {
        _username = username
        _userImg = userImg
    }

    init(userKey: String, postData: Dictionary<String, AnyObject>) {
        _userKey = userKey

        if let username = postData["username"] as? String {
            _username = username
        }

        if let userImg = postData["userImg"] as? String {
            _userImg = userImg
        }

        _userRef = Database.database().reference().child("messages").child(_userKey)
    }
}

它在 Swift 3 和 Firebase 3.0.2 下运行良好,但现在,一切都在更新,它总是崩溃。这不是任何其他问题的重复,因为它以前一直有效。

【问题讨论】:

  • 你为什么拥有那些私有财产?为什么它们被声明为隐式展开?
  • 这个错误有点像 if let username = postData["username"] as? String 所以发生的事情是您的 postData 节点之一没有用户名节点(还有其他原因),因此 var 没有被分配,因此为 nil。您可以使用 nil-coalescing 来防止崩溃并指定一个默认值,以防找不到该节点 let username = postData["username"] as?细绳 ?? “没有用户名!” 哦,我赞同@rmaddy 所说的话。
  • 我知道这是一个愚蠢的问题,但我现在如何解决“使用未解析的标识符'postData'”?另外,我学习了 YT 的旧课程,因为我几乎是初学者......
  • 你在哪里得到这个错误?另外,我建议将 Datasnapshot 传递给 init 方法而不是两个参数。这样一来,您就可以使用一个参数而不是两个参数来获取密钥和快照信息。
  • 不要发布大约 40 行代码,并在不告诉我们哪个行号引发错误的情况下说您遇到错误。

标签: swift firebase firebase-realtime-database


【解决方案1】:

我不确定我是否完全理解了这个问题或者究竟是什么导致了崩溃(它可能是一个丢失的子节点)或者隐式展开的类变量的用例是什么,但是为了回应评论,这就是我想要的在 Swift 4、Firebase 4 中执行

保留您的 Search 类,除了将 init 更改为以下内容(这被缩短以提供上下文)

init(withSnap: DataSnapshot) {
    _userKey = withSnap.key
    let dict = withSnap.value as! [String: Any]
    _username = dict["username"] as? String ?? "NO USER NAME!"
    _userImg = dict["userImg"] as? String ?? "NO IMAGE"
}

然后获取用户(例如)的 Firebase 函数将如下所示

let userRef = self.ref.child("users").child("uid_0")
userRef.observeSingleEvent(of: .value, with: { snapshot in
    let mySearch = Search(withSnap: snapshot)
    print(mySearch.userKey, mySearch.username, mySearch.userImg)
})

您需要添加其余的类代码以分配 _userRef 等。

这里的想法是为所需的类属性提供默认值,以防 Firebase 节点之一不存在并导致为零。即,如果 uid_0 没有用户名子节点,您的类将崩溃(确实如此)。使用上面的代码,该属性将被设置为默认值。

为了彻底起见,假设用户节点看起来像这样

users
  uid_0: "some string"   //the value here is a String, not a Dictionary

这会使我的代码崩溃。为了防止这种情况,请在 init 中添加更多错误检查

init(withSnap: DataSnapshot) {
    _userKey = withSnap.key
    if let dict = withSnap.value as? [String: Any] {
        _username = dict["username"] as? String ?? "NO USER NAME!"
        _userImg = dict["userImg"] as? String ?? "NO IMAGE"
    } else {
        _username = "No user data"
        _userImg = "No user data"
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 2016-10-18
    • 2017-04-09
    • 2018-09-22
    • 2016-06-26
    • 2016-03-12
    相关资源
    最近更新 更多