等待异步API调用完成 - Swift/IOS

5

我正在开发一个iOS应用程序,在我的appDelegate中有以下内容:

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {    
    self.api.signInWithToken(emailstring, token: authtokenstring) {
        (object: AnyObject?, error:String?) in            
            if(object != nil){
                self.user = object as? User
                // go straight to the home view if auth succeeded
                var rootViewController = self.window!.rootViewController as UINavigationController
                let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                var homeViewController = mainStoryboard.instantiateViewControllerWithIdentifier("HomeViewController") as HomeViewControllerenter
                // code here
                rootViewController.pushViewController(homeViewController, animated: true)
            }
        }
    return true
}
api.signInWithToken是使用Alamofire进行的异步调用,在func应用程序结尾返回true之前,我希望等待其完成。

2
Swift没有这种功能。你需要在didFinishLaunching的主体中设置窗口和根视图控制器,可能还要加上一个加载图形,然后在API登录完成处理程序中导航到新的视图控制器。 - Nate Cook
didFinishLaunching已经被弃用了,但这听起来像是一个好主意。 - brian S
2个回答

11

注意:不应该这样做,因为它会阻塞线程。请参考上面Nate的评论以获得更好的方法。

使用GCD可以等待异步调用完成,代码如下所示:

var semaphore = dispatch_semaphore_create(0)

performSomeAsyncTask {
    ...
    dispatch_semaphore_signal(semaphore)
}

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
dispatch_release(semaphore)

如果你对信号量一无所知,可以查看维基百科的文章


2
所以我移除了dispatch_release(semaphore),但是semaphore_wait似乎阻塞了整个线程。看起来执行在我的异步闭包中被卡住了。 - brian S
1
在学习的精神下,您能解释一下为什么我的评论是个坏主意吗? - Nate Cook
1
@NateCook 相反,我想表达的是你的评论包含了正确的方法!可能应该写成“如Nate所示,采用另一种方法”。对于误解我感到抱歉。 - Anton
@brianS 当然,它会阻塞线程。这正是你一开始所要求的。正如Nate建议的那样,只需使用回调函数来更新UI即可。 - Anton
是的,我想要阻塞线程,但是dispatch_semaphore_signal(semaphore)不能解除阻塞。这是否是预期的行为? - brian S
显示剩余4条评论

1

这是用Swift 3编写的解决方案。同样,它会阻塞线程直到异步任务完成,因此只应在特定情况下考虑使用。

let semaphore = DispatchSemaphore(value: 0)

performAsyncTask {
    semaphore.signal()
}

// Thread will wait here until async task closure is complete   
semaphore.wait(timeout: DispatchTime.distantFuture)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接