我在从Firebase数据库获取数据并将其添加到数组时遇到问题。
方法 getNewQuote 的打印输出显示该数组为空,但屏幕截图显示该标签已在 getNewQuote 方法中更新。

怎么会这样呢?
导致此问题的 getNewQuote 方法中的事件是否存在延迟?
此外,如何使用 getNewQuote 方法的第4次迭代而不是最后一次迭代来更新标签。

先感谢您!

代码分解
循环迭代5次并执行以下操作:
1.创建一个随机数
2.将随机数传递给方法getNewQuote
(此方法从数据库中获取数据,并将其追加到 quotesMessages 数组中)
循环迭代后,将打印完整的数组

代码:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var message: UILabel!

    var QuoteRef:String = "https://motivatr.firebaseIO.com/quotes"

    var quotesMessages = [String]()

    /* */
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        for (var i = 0; i < 5; i++) {
            var currRandomNumber = self.createRandomNum()
            self.getNewQuote(currRandomNumber)
        }

        println("viewDidLoad, array has \(quotesMessages.description)")
    }//eom

    /* */
    override func viewWillAppear(animated: Bool) {
        println("viewWillAppear, array has  \(quotesMessages.description)")
    }

   /* */
   override func viewDidAppear(animated: Bool) {
       println("viewDidAppear, array has  \(quotesMessages.description)")
   }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    /* creates a random number */
    func createRandomNum()-> Int {
        var randomNumberRange = UInt32(49)
        var UnsignedRandomNum = arc4random_uniform(randomNumberRange)
        var randomNum = Int(UnsignedRandomNum)

        return randomNum
    }

    /* gets a new data from databases */
    func getNewQuote(randomNum: Int){
        println("random number \(randomNum) created")
        //Temp var's
        var quoteText = ""
        var quoteAuthor = ""

        var DBQuoteURL = "\(QuoteRef)/\(randomNum)"
        var myRootRef =  Firebase(url:DBQuoteURL)
        myRootRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
            if snapshot.value is NSNull {
                // The value is null
            }
            else
            {
                if let quote = snapshot.value["quote"] as? String {
                    //                    println(quote)
                    quoteText = "'\(quote)'"
                    self.message.text = quoteText
                    self.quotesMessages.append(quoteText)
                }
            }
        })

        println("quote is: \(quoteText)")
    }//eom
}//eoc

从控制台输出:
random number 24 created
quote is:
random number 18 created
quote is:
random number 45 created
quote is:
random number 47 created
quote is:
random number 34 created
quote is:
viewDidLoad, array has []
viewWillAppear, array has  []
viewDidAppear, array has  []

Iphone屏幕快照:
ios - 将Firebase数据添加到iOS Swift中的数组-LMLPHP

最佳答案

您已经遇到了异​​步方法的奇妙问题!

我不知道您是否知道这一点,但是一块异​​步的代码在其他一切都继续进行的同时运行,即您的代码不会等待其完成继续。

这里发生的是,您的循环到达myRootRef.observeSingleEventOfType...段,启动了异步调用,然后继续运行,而不必完成所有代码。

这就是看起来好像是循环混乱,或者从未装满东西等等。

我不确定您想对self.message.text = quoteText中的getNewQuote做什么,但是以您拥有的方式,它只会使用最新下载的报价来更新标签。

如果您想使myRootRef.observeSingleEventOfType...代码中发生某些事情,请确保它在if let quote = snapshot.value["quote"] as? String {.......}的大括号内。
如果您想在下载完成后实现,可以尝试在if quotesMessages.count == 5 {...}中尝试使用if let计数器,或者尝试使用观察器或您喜欢的任何方法。

祝你好运!

10-04 21:22