完成异步请求后,在选择表后运行segue



我试图运行一个url请求,以获得一个JSON文件后,某个表行被选中,基于行一个唯一的ID与url请求发送和不同的JSON生成。这是prepareforSegue

    // MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
     // Get the new view controller using segue.destinationViewController.
    var divisionScene = segue.destinationViewController as! DivisionViewController
    // Pass the selected object to the new view controller.
    if let indexPath = tableView.indexPathForSelectedRow() {
    let arrayIndex = indexPath.row
       //println("Index: (arrayIndex)")
        torneoIDTransfer = torneos[arrayIndex].torneoID
        //println("(torneoIDTransfer)")

        //check second url with second request type same token
        //sets url to string using token
        let tercerURL = NSURL(string: "http://api.zione.mx/get.json.asp?tr=3&tkn=(tkn)&tor=(torneoIDTransfer)")
        //initializes request
        let request = NSURLRequest(URL: tercerURL!)
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue()) { response, jsonDataRequest3, error in
            let dataRequest3 = jsonDataRequest3
            //takes data, saves it as json
            let tercerJSON = JSON(data: jsonDataRequest3)
            //checks to see that contents != nil, meaning the JSON file was found
            if tercerJSON != nil {
                //checks amount of tournaments available in order to generate table.
                let divisionCount = tercerJSON["lista-divisiones"].count
                //sets global variable numero de torneos
                numeroDeDivisiones = divisionCount

                //for loop to go insert into Torneo nuevo each ID and name by using count from above
                for var index = 0; index < divisionCount; ++index {
                    var divisionID = Int(tercerJSON["lista-divisiones" ][index]["DivisionID"].number!)
                    var nomDivision = tercerJSON["lista-divisiones"][index]["nomDivision"].string
                    //println("(divisionID)")
                    //println("(nomDivision)")
                    var divisionNuevo = listaDivisiones(divisionID: divisionID, nomDivision: nomDivision!)
                    divisiones.append(divisionNuevo)
                    numeroDeDivisiones = 10
                    print("WHO IS FIRST")
                }
            }
            print("(divisiones[0].nomDivision)")
        }
    }
}

我通过从表格单元格拖动到新的视图控制器来创建segway。但是,当我单击表格单元格时,在请求有机会完成之前,转换立即发生,因此没有显示任何数据。

最好在用户选择表行之前就在后台获取和处理数据。如果这是不可能的,那么我建议让你的目标视图控制器做URL请求。URL请求是异步发生的,所以在你的源视图控制器被释放之前,它永远不会有机会完成。

在源视图控制器中,修改prepareForSegue

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var divisionScene = segue.destinationViewController as! DivisionViewController
    if let indexPath = tableView.indexPathForSelectedRow() {
        let arrayIndex = indexPath.row
        torneoIDTransfer = torneos[arrayIndex].torneoID
        let tercerURL = NSURL(string: "http://api.zione.mx/get.json.asp?tr=3&tkn=(tkn)&tor=(torneoIDTransfer)")
        divisionScene.fetchDataAtURL(tercerURL)
    }
}

你需要在目标视图控制器中定义一个方法来处理抓取。

func fetchDataAtURL(URL: NSURL) {
    let request = NSURLRequest(URL: tercerURL!)
    NSURLConnection.sendAsynchronousRequest( // ... your fetching logic here
}

您还需要一些逻辑来在数据到达时显示数据。我建议将其放入请求的完成回调中(或者更确切地说,让回调触发显示更新)。如果你的divisionScene是一个tableView,你可以调用reloadData(在你更新数据源之后)。如果没有,您将需要其他方式来更新UI。如果您正在更新UI,请确保dispatch到该部分的主队列。

这样做至少将URL加载责任传递给目标视图控制器,当数据最终到达那里时,它至少会存在。

"转换立即发生,在请求有机会完成之前"。

当然有,这正是异步的意思。你特意提到它是异步的,但你一定对它的含义有误解。解释一下你认为这意味着什么,以及你希望你的代码是什么,这样你就可以更好地接受我们的教育。

当你调用sendAsynchronousRequest()时,把你的程序想象成两个分支(实际上这就是有效发生的事情)。一部分是你的原始代码它会继续执行也就是说你的prepareFoSegue代码会继续执行。同时,操作系统将并行地执行请求,当请求完成时,传递给sendAsynchronousRequest()的块中的代码将被执行。因此,您的prepareForSeque()函数将在收到Json之前完成。

但除此之外,你不应该尝试或希望或希望JSon在segue转换之前被获取-这样做会中断你的ui。假设sendAsynchronousRequest()而不是sendSynchronousRequest(),它花了10秒来完成,你认为你的应用程序运行时的后果是什么?

您应该在GUI准备好显示数据之前很长时间获取数据,或者如果不可能,立即显示没有数据的GUI,然后在数据到达时更新它。

最新更新