Swift变量范围问题

时间:2015-05-25 23:10:58

标签: ios swift

我在我的viewcontroller中将arr1和arr2声明为全局数组。

在以下函数中,我在解析查询中添加它们。当我在查询中的arr1之前不包含“self”时,Xcode会出错,因此我将其包含在内。在查询之外,在我下面标记的空间中,我尝试访问arr1和arr2。但无论我是否尝试self.arr1或arr1,该数组在那时都变为空。我认为这是swift的某种范围问题,而且我遇到了很多麻烦所以任何帮助都会非常感激。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "vF") {
        var destVC = segue.destinationViewController as vF

        destVC.namePassed = fV

        var query = PFQuery(className:"class")
        query.whereKey("createdBy", equalTo:fV)

        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]!, error: NSError!) -> Void in
            if error == nil {
                // The find succeeded.
                NSLog("Successfully retrieved \(objects.count) records.")
                // Do something with the found objects

                for object in objects {
                    self.arr1.append(object["field1"]! as Int)
                    self.arr2.append(object["field2"]! as String)
                }

            } else {
                // Log details of the failure
            }

        }

        // I want to access arr1 and arr2 right here, but when I do they come up empty
        // I have tried accessing with self.arr1 and arr1 but neither works 
    }

}

2 个答案:

答案 0 :(得分:1)

findObjectsInBackgroundWithBlock是异步的,因此它会在后台线程中发生,而你的程序仍然在主线程中运行,然后你的后台线程回调你需要编程的数据是为什么传递你指出的点。 解决问题的最佳解决方案之一是为arr1和arr2添加观察器,以便在发生时通知您。添加观察者到数组可能有点技巧,我想让你保持简单,所以我建议你创建一个布尔变量,告诉你什么时候值完成更改。为此,您需要创建像这样的变量

var arrayDidChange:Bool = false {
    didSet{
        if arrayDidChange{
            callFuncDataReadArrayHere()
        }
    } 
}

现在,每当你更改数组中的值(添加或编辑)时,你将arrayDidChange设置为true,并在callFuncDataReadArrayHere结束之后执行所有操作,将arrayDidChange设置为false。

这样,您将始终确保在填充后访问数组中的值。

我希望能帮到你!

答案 1 :(得分:0)

您应该直接从控制器而不是单元连接segue。实现didSelectRowAtIndexPath,并将查询放在那里,并调用performSegueWithIdentifier:sender:在异步方法的完成块内。现在,当您实现prepareForSegue时,数组将可用于传递到目标视图控制器。

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    var query = PFQuery(className:"class")
    query.whereKey("createdBy", equalTo:fV)

    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            // The find succeeded.
            NSLog("Successfully retrieved \(objects.count) records.")
            // Do something with the found objects

            for object in objects {
                self.arr1.append(object["field1"]! as Int)
                self.arr2.append(object["field2"]! as String)
            }
            self.performSegueWithIdentifier("vF", sender: self)

        } else {
            // Log details of the failure
        }

    }
}

在segue实际采用这种方法之前会有一些延迟,因为它会在findObjectsInBackgroundWithBlock返回结果之前发生。如果这是不可接受的,那么你仍然可以在prepareForSegue中传递数组(在"对象中的对象"子句之后显示的相同位置),但是数组将不会立即可用在目标视图控制器中,您将不得不处理它。