我试图确保我的云访问完成之前继续主线程。我从一个警报动作中调用downloadRecordsWithCompletion,所以我在一个框中。
self.downloadRecordsWithCompletion() {
error in
println("out of alert")
println("raceIdentities.count = (raceIdentities.count)")
println("raceTeams.count = (raceTeams.count)")
println("raceTasks.count = (raceTasks.count)")
self.misc()
}
下面是代码:
func downloadRecordsWithCompletion(completion: (error: NSError?) -> Void) {
dispatch_async(GlobalUserInitiatedQueue) {
var storedError: NSError!
var downloadGroup = dispatch_group_create()
dispatch_group_enter(downloadGroup)
self.cloudReadRaceIdentities(self.isMonitor)
dispatch_group_leave(downloadGroup)
dispatch_group_enter(downloadGroup)
self.cloudReadParameters()
dispatch_group_leave(downloadGroup)
dispatch_group_enter(downloadGroup)
self.cloudReadCheckpoints()
dispatch_group_leave(downloadGroup)
dispatch_group_enter(downloadGroup)
self.cloudReadTeams()
dispatch_group_leave(downloadGroup)
dispatch_group_enter(downloadGroup)
self.cloudReadTasks()
dispatch_group_leave(downloadGroup)
/*
dispatch_group_enter(downloadGroup)
self.cloudReadRaceIdentities(self.isMonitor)
self.cloudReadParameters()
self.cloudReadCheckpoints()
self.cloudReadTeams()
self.cloudReadTasks()
dispatch_group_leave(downloadGroup)
*/
dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER)
dispatch_async(GlobalMainQueue) {
//if let completion = completion {
completion(error: storedError)
//}
}
}
}
无论我尝试了什么,当点击
时,它总是会抛出"致命错误:在展开可选值时意外发现nil"。println("raceIdentities.count = (raceIdentities.count)")
因为从这行调用的代码:
self.cloudReadRaceIdentities(self.isMonitor)
还没有发生。
我尝试了注释掉的代码(没有成功),也改变了这一行:
dispatch_async(GlobalUserInitiatedQueue) {
dispatch_sync(GlobalUserInitiatedQueue) {
我还将println语句移出了外壳,结果相同。
我的大部分信息来自raywenderlich.com上的Swift大中央调度教程,但显然我遗漏了一些东西。
任何想法吗?
你必须:
- 让你的阅读器功能同步。然后你也可以删除所有的
- 添加一个完成处理程序到你的阅读器函数中,在其中留下
dispatch_group
dispatch_group
的东西(无论如何它没有做什么你现在有它)func downloadRecordsWithCompletion(completion: (error: NSError?) -> Void) {
dispatch_async(GlobalUserInitiatedQueue) {
self.cloudReadRaceIdentities(self.isMonitor)
self.cloudReadParameters()
self.cloudReadCheckpoints()
self.cloudReadTeams()
self.cloudReadTasks()
dispatch_async(GlobalMainQueue) {
completion(error: nil)
}
}
}
第二个方法看起来像这样(在给阅读器函数添加一个完成处理程序参数之后):
func downloadRecordsWithCompletion(completion: (error: NSError?) -> Void) {
dispatch_async(GlobalUserInitiatedQueue) {
let downloadGroup = dispatch_group_create()
dispatch_group_enter(downloadGroup)
self.cloudReadRaceIdentities(self.isMonitor) {
dispatch_group_leave(downloadGroup)
}
dispatch_group_enter(downloadGroup)
self.cloudReadParameters() {
dispatch_group_leave(downloadGroup)
}
dispatch_group_enter(downloadGroup)
self.cloudReadCheckpoints() {
dispatch_group_leave(downloadGroup)
}
dispatch_group_enter(downloadGroup)
self.cloudReadTeams() {
dispatch_group_leave(downloadGroup)
}
dispatch_group_enter(downloadGroup)
self.cloudReadTasks() {
dispatch_group_leave(downloadGroup)
}
dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER)
dispatch_async(GlobalMainQueue) {
completion(error: nil)
}
}
}
哦,这也可能不起作用(忘记上面的),因为只有一个组,但有多个点可以离开。所以你可能想使用dispatch_semaphore
,直到它被发出n次信号,像这样:
func downloadRecordsWithCompletion(completion: (error: NSError?) -> Void) {
dispatch_async(GlobalUserInitiatedQueue) {
let semaphore = dispatch_semaphore_create(5)
self.cloudReadRaceIdentities(self.isMonitor) {
dispatch_semaphore_signal(semaphore)
}
self.cloudReadParameters() {
dispatch_semaphore_signal(semaphore)
}
self.cloudReadCheckpoints() {
dispatch_semaphore_signal(semaphore)
}
self.cloudReadTeams() {
dispatch_semaphore_signal(semaphore)
}
self.cloudReadTasks() {
dispatch_semaphore_signal(semaphore)
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
dispatch_async(GlobalMainQueue) {
completion(error: nil)
}
}
}
但是我仍然建议让你的读函数同步,因为你已经在你的方法中异步了