我尝试确保在继续主线程之前完成了我的云访问。我在一个警报操作中调用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 Grand Central Dispatch Tutorial,但显然我错过了一些东西。
有什么想法吗?
答案 0 :(得分:0)
您必须:
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)
}
}
}
但是我仍然建议让你读取函数同步,因为你的方法已经异步
了