【问题标题】:Why is my closure not called when I expect it to be?为什么我的闭包在我期望的时候没有被调用?
【发布时间】:2023-04-09 11:24:01
【问题描述】:

在学习 Swift 时,我从来没有真正理解过的一件事是闭包。我总是觉得和他们一起工作很困惑。

谁能解释一下我在下面的代码中做错了什么。

for id in myCircles{
    var circleName = ""
    var circleCategory = ""
    var circleID = ""
            
            
            
    ref.child("\(id)").observeSingleEvent(of: .value, with: { snapshot in
        
        let value = snapshot.value as? NSDictionary
        circleName = value?["name"] as? String ?? ""
        circleCategory = value?["category"] as? String ?? ""
        circleID = value?["id"] as? String ?? ""
                
                
        self.defaults.setValue([circleName, circleID, circleCategory], forKey: "newestCircle"+"\(id)")

   }) { error in
              
      }
            
//the problem is that the part below gets executed before the closure, which is when the value should be added. The part below must be executed after the closure.
            
    let retrievedData = self.defaults.value(forKey: "newestCircle"+"\(id)") as? [String] ?? ["","",""]
    
    self.addCircle(circleName: retrievedData[0], circleID: retrievedData[1], circleCategory: retrievedData[2])
             
 }

正如评论所说,我的 .observingSingeEvent 闭包是在闭包下方的代码之后调用的。它不仅在闭包下面的代码之后被调用,而且在整个 for 循环之后被调用,如果它在循环内部被调用的话,它会被调用多次。我不明白这是为什么,有人可以帮助我吗?

【问题讨论】:

标签: ios swift firebase firebase-realtime-database closures


【解决方案1】:

闭包只是匿名函数。没有区别

func sum(_ a: Int, _ b: Int) -> Int {
    a + b
}

let sum: (Int, Int) -> Int = { a, b in a + b }

这两个函数做的事情完全相同,将两个整数相加,但它们以不同的形式表示,一个作为函数,一个使用闭包语法,两者都是可以互换的。它们之间最大的区别在于函数是命名的,而闭包是匿名的。我们将闭包存储在一个名为 sum 的变量中,但闭包本身没有名称。

对于您的具体问题,我没有使用 Firebase,但发生的是这个电话

    ref.child("\(id)").observeSingleEvent(of: .value, with: { snapshot in
        
        let value = snapshot.value as? NSDictionary
        circleName = value?["name"] as? String ?? ""
        circleCategory = value?["category"] as? String ?? ""
        circleID = value?["id"] as? String ?? ""
                
                
        self.defaults.setValue([circleName, circleID, circleCategory], forKey: "newestCircle"+"\(id)")

   }) { error in
              
      }

正在异步执行。 ref.child.observeSingleEvent 将闭包作为参数并稍后调用它,这意味着闭包的执行与您的其余代码完全分开。这就是为什么您会看到打印不同步的原因,因为闭包是异步执行的。

顺便说一句,尽量避免使用NSDictionary,除非你绝对必须使用新的 Swift 并发特性来代替闭包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多