【问题标题】:Extract Value from Block Swift从 Block Swift 中提取价值
【发布时间】:2016-07-17 14:47:24
【问题描述】:

我希望能够在块外使用 currentVote Int,其中 currentVote 是定义在类顶部的变量。

databaseRef.child("Jokes").child(currentKey).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

           if let currentNumber = snapshot.value! as? [String: AnyObject] {

              let currentValue = (currentNumber["votes"] as? Int)!

             self.currentVote = currentValue


            }

        })

 //*Location* where i want to use currentVote with it's new value

Location 是我想使用 currentVote 值的地方。当我在这里打印值时,我返回 nil,此后我将返回预期值。当我在块内打印值时,我得到了预期值。我理解为什么会这样,这是因为该块是在主线程之外执行的,因此当我在块之外打印时,打印是在块之前执行的,因此它的值为 nil。我知道要将它放到主线程上,您必须使用

dispatch_async(dispatch_get_main_queue(), {
            code
        })

但是,我在这个调度调用中以多种不同的方式嵌套了我的代码,但无法获得 currentVote 的新值。我搜索了堆栈溢出,用户建议在块外创建一个函数,然后在内部调用它。但是,它们的功能涉及

func printValue(value: Int) {

print(value)

}

正如您所见,这对我来说毫无用处,因为我想使用块之外的值,而不是打印它!

***根据 Cod3rite 建议修改的代码****

func get(completion: (value: Int) -> Void) {

        databaseRef.child("Jokes").child(currentKey).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

           if let currentNumber = snapshot.value! as? [String: AnyObject] {

              let currentValue = (currentNumber["votes"] as? Int)!

             self.currentVote = currentValue

            completion(value: self.currentVote!)

            }

        })

        }

//where I want to use currentVote

我已经按照建议将它放入完成,但我仍然不知道如何获取变量!

【问题讨论】:

  • 任何异步处理都需要使用completion才能返回值。可以在这里参考我的答案stackoverflow.com/questions/38113280/…
  • @cod3rite 我想我已经根据您的其他帖子进行了更改,但我仍然无法使用 currentVote 值。这些变化在我上面的问题中。非常感谢您抽出宝贵时间,如果您能给我一个完整的答案,我将不胜感激。
  • 您无法访问要访问的变量。当您的控制流在那里时,它还没有准备好。准备好后,您需要对块内的变量执行任何操作。
  • (“不能”在技术上并不准确,但您现在应该假设它是。)
  • @AaronBrager 好的,所以我正在使用 firebase,我想使用 currentVote 变量更新我的树中特定 JSON 数据的值。所以你建议我在当前的 observeEvent 块中这样做?我认为观察一个事件然后在该调用中更新数据可能是不好的做法?我不知道为什么只是猜测,或者这样可以吗?

标签: swift multithreading firebase firebase-realtime-database


【解决方案1】:

你几乎猜对了。但这里有一些你需要做的修改:

func get(completion: (value: Int) -> Void) {

        databaseRef.child("Jokes").child(currentKey).observeSingleEventOfType(.Value, withBlock: { (snapshot) in

           if let currentNumber = snapshot.value! as? [String: AnyObject] {

              let currentValue = (currentNumber["votes"] as? Int)!
               completion(value: currentValue)

            }


        })

        }

现在,当您想调用此get 时,请执行以下操作:

get { value in
 //Now you have your value retrieved from firebase and you can use it however you want.
 print(value)
 self.currentVote = value
//your other code
}

【讨论】:

  • 感谢 Dershowitz,非常高兴您能提供完整的答案。最后,我没有使用完成处理程序,我只是将我的代码放在数据检索下面,这样做有什么问题吗?我的代码涉及将 Int 值增加 1,然后保存 JSON 树上当前存储的值。
  • 只有一个问题。发生错误时,您的代码将失败,因为将不会从 JSON 返回 Int
  • 好的,我明白了,非常感谢您的时间和帮助!
  • 随时!快乐编码:)
猜你喜欢
  • 2014-09-13
  • 2016-01-10
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 2020-04-30
相关资源
最近更新 更多