ios swift 解析:具有异步结果的方法

ios swift parse: methods with async results

当我转到 viewController 时,我在 viewDidAppear 方法中调用了一个函数:

override func viewDidAppear(animated: Bool) {
    getLessons()
}

此方法从 parse.com 加载我想在 pickerView 中使用的数据列表。 函数本身:

func getLessons(){
        var query = PFQuery(className:"Lesson")
        query.orderByAscending("name")
        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]!, error: NSError!) -> Void in
            if error == nil {

                for object in objects {

                    var name = object["name"] as String

                    self.languagePickerKeys.append(object.objectId)
                    self.languagePickerValues.append(name)

                    self.selectedLanguage.text = self.languagePickerValues.first // set the first lessons name into the text field
                    self.selectedLessonObjectId = self.languagePickerKeys.first // set the first objectId for the lesson

                    self.languagePicker?.reloadAllComponents()

                }
            } else {
                // Log details of the failure
                println("\(error.userInfo)")
            }
        }
        println("getLessons done")
    }

事实是,文本字段是空的,因为 getLesson() 获取数据异步并且数据对文本字段不可用。

我也尝试将 getLesson 放入 viewDidAppear 方法中,但这对我没有帮助,反正文本字段是空的。

我能做什么,准备好来自 getLessons() 方法的数据,并在向用户显示视图时将其第一个值加载到我的文本字段中?

在将其设置为 pickerView 之前,您当然必须从 asyncTask 获取数据。

这是实例化后的 ViewController 生命周期:

  • 如果被转至,请做好准备。
  • 插座设置
  • 出现和消失。

所以,你有两个选择:

  1. 加载之前ViewController中的数据,然后执行segue。您需要按照以下步骤操作。

    一个。创建一个从之前的 ViewController 到你的 ViewController 的转场。

    b。当你想下一步时调用函数 ViewController 获取数据,最后(在获取数据后)调用 performSegueWithIdentifier 这将导致你的 ViewController.

    c。在prepareForSegue

    中设置数据
    let navigationController = segue.destinationViewController as UINavigationController
    
    navigationController.data = yourData //you got from async call
    

现在当您到达 ViewController 时,您确定您的数据存在,您可以将其设置到您的 pickerView。

  1. 如果你想在同一时间做它ViewController:这是ViewController的生命周期:所以你需要在viewDidLoad中调用你的函数,并始终设置你的异步网络调用完成后的 pickerView。

确保从主线程启动对 UI 的所有更改,例如像这样:

dispatch_async(dispatch_get_main_queue(), {
    selectedLanguage.text = languagePickerValues.first
    self.languagePicker?.reloadAllComponents()    
})

问题在于 findObjectsInBackgroundWithBlock 是一个异步方法,因此即使您在 ViewDidLoad 中触发它,您也永远不知道何时会收到响应数据,并且您无法确定数据是否已准备好您查看的时间出现。

我认为你只有两种可能: 第一个是在之前的视图控制器中加载数据,然后将准备好的数据传递给您的视图控制器。

第二种方法是使用同步方法(可能是 findobject 方法?)并将调用放在视图出现之前触发的方法中(如 viewWillAppear: 方法)。但是当数据正在检索时,您的视图会停留片刻(我认为)......然而,第二种解决方案可能会解决您的问题,但是使用同步方法从较慢的数据源检索数据通常是糟糕的设计解决方案。

D.