在Swift Class中向Array添加值,但Array声称在测试时它是空的

时间:2015-03-09 01:50:40

标签: arrays swift parse-platform self

我正在尝试使用存储在在线数据库(Parse)上的数据创建一个整数数组。我知道我收到数据并且我的变量存储了这些数据。我也知道数据值正在被添加,因为当我在追加行下打印出数组的大小时,大小会不断增加,直到达到我的数据库的大小(90)。但是,当我在方法结束时或在我的构造函数中打印数组的大小时,我得到的值为0.我感觉这个问题正在发生,因为" self"关键字,但我不知道如何解决它。我的最终目标是将数据库中的所有值存储到我创建的数组中,并且可以全局访问。

以下是代码:

import Foundation

class DataLoader
 {
    var allData: [Int] = []

    init()
    {
        allData = []
        generateAllData()
        println(allData.count)
    }


    private func generateAllData()
    {
        var tempVal: Int = 0
        var tempArray: [Int] = []
        Parse.setApplicationId("CENSORED FOR PRIVACY REASONS", clientKey: "CENSORED FOR PRIVACY REASONS")
        var query = PFQuery(className: "Snapshot")
        query.selectKeys(["objectID"])
        query.findObjectsInBackgroundWithBlock
            {
                (objects: [AnyObject]!, error: NSError!) -> Void in
                if error == nil
                {
                    for obj in objects
                    {
                        var temp: String = obj.objectId
                        var newQuery = PFQuery(className: "Data")

                        newQuery.getObjectInBackgroundWithId(temp)
                            {
                                (dataValue: PFObject!, error: NSError!) -> Void in
                                if error == nil && dataValue != nil
                                {
                                    tempVal = dataValue["Year"].integerValue
                                }
                                else
                                {
                                    println(error)
                                }
                        }

                        self.allData.append(tempVal)
                        println(self.allData.count)
                    }
                }
        }
        println(allData.count)
    }
 }

1 个答案:

答案 0 :(得分:0)

问题是当后台操作仍在获取数据时,方法结束时和初始结束时的println正在发生。

当你调用" query.findObjectsInBackgroundWithBlock"时,它将进入后台并获取数据。但这并不会阻止下一行被调用,也不会阻止函数返回。

我建议您添加一个回调或委托方法,以便其余代码知道数据何时完全下载。

你使用" self"是正确的。在块内,您必须提供该上下文。

<强>更新 添加有关块和回调的更多信息。

当您使用块时,块之后的代码将继续,而不等待块完成。因此,一个很好的方法来了解块何时完成它以将回调函数作为包含块的函数的参数之一发送。块完成后,可以使用回调函数进行报告。

作为一个比你的代码更短的例子,看一下这个动画函数:

doSomeAnimation()    // call the function below

func doSomeAnimation() {
    println("Starting doSomeAnimation")

    UIView.animateWithDuration(2.0,
        animations: { () -> Void in
            // animate something here
            self.alphaButton.alpha = 1.0
        }) { (animationDone) -> Void in
            // animation over
            println("Animation complete")
    }

    println("Ending doSomeAnimation")
}

你会看到它包含3个println()语句,它们出现的顺序可能让你感到惊讶:

  1. 启动doSomeAnimation
  2. 结束doSomeAnimation
  3. 动画完成
  4. 因此doSomeAnimation()函数在动画完成之前就已经过了很长时间。在这个简单的例子中,这并不重要,但如果你需要知道其他代码可以继续下去呢?

    一种解决方案是使用块向函数发送回调函数。以下是前一个回调示例:

       doSomeAnimation() { (complete : Bool) in
           println("Animation callback")
       }
    
       func doSomeAnimation(callback : ( Bool ) -> Void) {
            println("Starting doSomeAnimation")
            UIView.animateWithDuration(2.0,
                animations: { () -> Void in
                    // animate something here
                    self.alphaButton.alpha = 1.0
                }) { (animationDone) -> Void in
                    // animation over
                    println("Animation complete")
                    callback(animationDone)
            }
    
            println("Ending doSomeAnimation")
        }
    

    因此调用doSomeAnimation()函数,但它提供了一个函数作为其参数。它执行动画,当动画结束时,它使用提供的回调函数向呼叫者报告。

    现在println()语句显示如下:

    1. 启动doSomeAnimation
    2. 结束doSomeAnimation
    3. 动画完成
    4. 动画回调
    5. 希望这更清楚,问题是什么是可能的解决方案。