我正在制作一个非常基本的应用程序,该应用程序具有搜索字段来获取传递到表格视图的数据。

我想做的是运行一个异步任务来获取数据,如果成功提取了数据,请转到下一个视图,在加载过程中,屏幕一定不要冻结,这就是为什么需要异步部分的原因。

当用户按下搜索按钮时,我运行以下代码以获取我的数据

override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {


方法。

    var valid  = true
    let searchValue = searchField.text
    let session = NSURLSession.sharedSession()

    let url = NSURL(string: "https://someapi.com/search?query=" + searchValue!)



    let task = session.dataTaskWithURL(url!, completionHandler: {(data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
        if let theData = data {
            dispatch_async(dispatch_get_main_queue(), {
                //for the example a print is enough, later this will be replaced with a json parser
                print(NSString(data: theData, encoding: NSUTF8StringEncoding) as! String)

            })
        }
        else
        {
            valid =  false;
            print("something went wrong");
        }
    })

    UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    task.resume()
    return valid;


我删除了一些检查连接/更改文本的代码,以显示应用程序正在加载数据以使代码更具可读性。
这是我有问题的部分,它是在进行所有检查之后确定的,我确定在此部分我有连接等。

发生的事情是它返回true(我可以看到这是因为加载了视图),而且还会从else语句中记录“出了点问题”。

我了解这是因为在有效值设置为false之前,返回有效值(在最后一行)返回有效值。
如果成功获取了数据,我怎么才能只返回true(改变视图),如果出了问题,怎么不显示下一个视图?

最佳答案

因为您希望数据获取是异步的,所以您无法返回值,因为返回值是同步的(当前线程必须等到函数返回后再使用该值)。您要使用的是回调。因此,当获取数据时,您可以执行操作。为此,您可以使用闭包,因此您的方法将是:

func shouldPerformSegue(identifier: String, sender: AnyObject?, completion:(success:Bool) -> ());


只需在completion(true)块中调用completion(false)session.dataTaskWithURL即可,具体取决于成功与否,并且在调用函数时,为completion提供一个块,在其中您可以执行检测或不执行检测success参数。这意味着您不能override该方法执行所需的操作,必须实现自己的机制。

07-26 09:30
查看更多