【问题标题】:Value getting reinitialised out of closure价值在关闭后重新初始化
【发布时间】:2018-10-03 09:46:09
【问题描述】:

我创建了一个对象数组 playerArray 来存储玩家的数据,然后我通过 ref 调用 firebase 数据库。在闭包中,我确实从 firebase 获取值并将其分配给属性 .name 但在闭包中,值被重新初始化为初始值。

var playerArray:[model] = [model]()

let ref = Database.database().reference().child("Players").child("Ronaldo")


func read(){

    ref.observe(.value) { (snap) in
        var val = snap.value as! Dictionary<String,AnyObject>
        let name = val["Name"] as! String
        let Model = model()
        Model.name = name
        self.playerArray.append(Model)
        print(snap)
    }

} 
 override func viewDidLoad() {
    super.viewDidLoad()
    read()
    table.delegate = self
    table.dataSource = self
    table.reloadData()
}

【问题讨论】:

  • 与问题无关 - 使用 lowerCamelCase 作为变量名,使用 UpperCamelCase 作为类型名。
  • 使用single observer 而不是observe,在关闭时重新加载表,因为在重新加载表的位置不会获得数据。

标签: ios swift firebase asynchronous


【解决方案1】:

您应该在更改参数后重新加载您的表格。在 viewDidLoad() 它只发生一次。

【讨论】:

    【解决方案2】:

    问题是在read 异步检索数据后,您不会重新加载表视图。您只需要从observe 的完成处理程序内部调用reloadData

    ref.observe(.value) { (snap) in
        var val = snap.value as! Dictionary<String,AnyObject>
        let name = val["Name"] as! String
        let Model = model()
        Model.name = name
        self.playerArray.append(Model)
        DispatchQueue.main.async {
            self.table.reloadData()
        }
    }
    

    也无需在viewDidLoad 中调用reloadData

    【讨论】:

    • 为了检查对象模型 id 是否附加到 playerArray,我在调用函数后在 viewdidLoad() 中打印了 playerArray[0] 并且应用程序崩溃
    • @Tushar 似乎您误解了异步方法的工作原理。当viewDidLoad 完成同步执行时,read 仍在异步执行,因此playerArray 为空,因此当您尝试访问其索引为 0 处的元素时,您将得到索引越界错误。该值仅在observe的完成处理程序中添加到数组中,因此您无法从完成处理程序外部访问它。
    • 感谢您的澄清 :)
    【解决方案3】:

    在闭包体中附加playerArray后,你应该刷新tableview

    override func viewDidLoad() {
        super.viewDidLoad()
        table.delegate = self
        table.dataSource = self
        read()
    }
    
    
    func read(){
    
        ref.observe(.value) { (snap) in
            var val = snap.value as! Dictionary<String,AnyObject>
            let name = val["Name"] as! String
            let Model = model()
            Model.name = name
            self.playerArray.append(Model)
            print(snap)
            self.table.reloadData()
    
        }
    
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-28
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      相关资源
      最近更新 更多