变量的值在关闭时访问

时间:2018-06-21 16:36:39

标签: ios swift closures

我编写了以下代码,当从闭包中访问时,变量“ total”的值又变回了初始值,即4

func getTotal() -> Int{

   let task = totalDB.observe(.value) { (snapshot) in
        if let data = snapshot.value as? Dictionary<String,AnyObject> {
            let jsonData = JSON(data)

            print("\n\n\n\n",jsonData,"\n\n\n\n\n")
            print(self.total,"\n\n")
            self.total=jsonData["Total"].intValue

        }
    }

return total

}

我初始化了变量:

    var total:Int = 4

3 个答案:

答案 0 :(得分:1)

如果您要问为什么getTotal()返回的值可能与闭包中的值不同,这几乎可以肯定,因为该函数在之前中返回了代码。关闭正在执行。您可以在Xcode中确认这一点,方法是在self.total=jsonData...行上设置一个断点,然后在return total行上设置另一个断点,然后看看哪个断点首先被命中。

答案 1 :(得分:0)

我将使用完成处理程序来解决这个问题。

func getTotal(_ completion: @escaping(_ error: Error?, _ value: Int?) -> Void) {
       let task = totalDB.observe(.value) { (snapshot) in
            if let data = snapshot.value as? Dictionary<String,AnyObject> {
                let jsonData = JSON(data)

                print("\n\n\n\n",jsonData,"\n\n\n\n\n")
                print(self.total,"\n\n")
                completion(nil,jsonData["Total"].intValue)

            } else { completion(NSError(domain: "Data not found", code: 0, userInfo: nil),nil) }
        }
    }

上面的这段代码将获取总值并将其传递给处理程序。然后,您可以在调用getTotal()函数时访问它。如果收到错误输出,您将知道您不正确地访问快照。

以下是如何使用新功能的示例:

....

// wherever you need the int value
var myNum = 0

getTotal({ (error, num) in 
    if error != nil { 
        print("error getting data", error!.localizedDescription) 
    } else { 
        myNum = num // do what you want here
    }
})

答案 2 :(得分:0)

您不能具有异步函数/闭包的返回值。在您的情况下,totalDB.observe(.value)将异步执行传递的闭包,而return语句是同步语句,因此即使在执行闭包之前,return语句也会被执行。

您需要的是完成框

func getTotal(@escaping completionBlock : ((Int) -> ())) {
        let task = totalDB.observe(.value) {[weak self] (snapshot) in
            guard let strongSelf = self else {
                return
            }

            if let data = snapshot.value as? Dictionary<String,AnyObject> {
                let jsonData = JSON(data)
                print("\n\n\n\n",jsonData,"\n\n\n\n\n")
                print(strongSelf.total,"\n\n")
                strongSelf.total=jsonData["Total"].intValue
                completionBlock(strongSelf.total)
            }
        }

    }

最后,您可以将其命名为

    self.getTotal() {[weak self] value in
        guard let strongSelf = self else {
            return
        }
        debugPrint("do whatever you wanna do with total here")
    }

不建议将强壮的自我传递给封闭,弱弱/无主的自我,并使用安全防护让自己更安全地访问自我,以确保您不会因为自身不可用而陷入保留周期/崩溃。

希望这会有所帮助