【问题标题】:Firebase While Loop Swift 4Firebase While 循环 Swift 4
【发布时间】:2017-11-04 21:25:07
【问题描述】:

我在我的一个应用中处理新页面时遇到了一个涉及 Firebase 和 While 循环的小问题。以下是我的代码:

var user = User()

var i = 0

while i < 101 {

print("Print Statement 1: " + String(i))

//Correctly prints i, incrementing it by 1 every time like it should.

self.ref.child("Directory")
    .child(String(i))
    .observeSingleEvent(of: .value, with: { (snapshot) in

        print("Print Statement 2: " + String(i))

        //Always prints 101

        let nameValue = snapshot.value as? NSDictionary

        if nameValue != nil {

            user.id = String(i)

            //Always get set to 101, and not the current value of i

        }

    }) { (error) in

        print(error.localizedDescription)

}

i += 1

}

日志:

打印声明 1:

0
1
2
3
4
etc.

打印语句 2:

101
101
101
101
101
etc.

几乎我在这里唯一的问题是为什么第二个打印语句总是打印 101 而不是 i 的增量值。这是否与 Firebase Observer 每次执行 while 循环时都没有观察到单个事件有关?另外,我该怎么做才能解决这个问题?

谢谢, 关键绩效指标

【问题讨论】:

  • 第一;不要那样做。 Firebase 是异步的,while 循环的触发速度比从互联网返回的数据要快得多。第二;你想具体完成什么? Firebase 中的数据仅在闭包内有效,因此这是唯一应该使用它的时间。在这种情况下,while 循环将达到 101 在 firebase 可以从 firebase 检索数据之前并完成一次关闭。例如如果您必须在一个紧密的循环中运行 Firebase,那么您可能做错了。
  • 是的,这就是整个问题。还有什么我可以做的吗?我正在尝试遍历数据库中的所有项目以查看其中哪一项存在。当我找到一个存在时,我将 user.id 设置为存在的那个的编号,然后我从 nameValue 变量中获取所有数据并将其放入一个数组中。将延迟添加到 while 循环的末尾是否可以解决此问题?
  • 无需循环。只需检查节点是否存在(不为零)。请参阅我对this question的回复
  • 问题是,我不知道数据是存储在 Directory/0 还是 Directory/15 下,这就是为什么我试图遍历所有可能的 Directory/i 目录并获取那些存在的。
  • 能否请您附上您的 Firebase 结构的快照(请作为文本,不要图片。Firebase 控制台->导出 JSON)。还用您正在寻找的 data 更新您的问题;即 /Directory/0/data_being_looked。此外,看起来(目前)您已将目录命名为 0、1、2,这是一个数组。在 Firebase 中通常应避免使用数组,因此可能有更好的方法来构建数据。

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

这是因为 firebase 异步查询您的请求和完成处理程序(您在其中打印 i),所以当您的 while 循环完成并且 i 的值为 101 时碰巧被调用。

编辑:一种解决方法是有一个单独的计数器并仅在您检查值时递增。因此,只有当结果出现并且您可以知道哪个结果为零时才会改变。但是,这并不可靠,因为网络请求可能很慢且无序,但在大多数情况下应该可以工作

var user = User()

var i = 0

var counter = 0

while i < 101 {

...

self.ref.child("Directory")
    .child(String(i))
    .observeSingleEvent(of: .value, with: { (snapshot) in

        ...

        let nameValue = snapshot.value as? NSDictionary

        if nameValue != nil {

            user.id = String(i)
            // prints the item number
            print(counter)

        }
        // increment the counter when you actually have data
        counter += 1

    }) { (error) in

        print(error.localizedDescription)

}

i += 1

}

【讨论】:

  • 哦,好的,有没有办法让我在 nameValue 不为 nil 的情况下捕获 i 的值?
  • 一种解决方法是有一个单独的计数器并仅在您检查值时递增。因此,只有当结果出现并且您可以知道哪个结果是 nil 时才会改变。但是,这并不可靠,因为网络请求可能很慢且无序,但在大多数情况下应该可以工作
  • 嗨 Anushk,你能给出一个代码示例吗?谢谢。
  • 很高兴它有帮助:) 请接受答案stackoverflow.com/help/someone-answers
猜你喜欢
  • 1970-01-01
  • 2023-03-22
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多