简体   繁体   English

Swift中void函数中的dispatch_async和意外的非void返回值

[英]dispatch_async and unexpected non-void return value in void function in Swift

I have a function in my appDelegate that returns user's current location. 我的appDelegate中有一个返回用户当前位置的函数。

Now I want to call it asynchronously at some other place and I did: 现在我想在其他地方异步调用它,我做到了:

func handleLocation() -> CLLocation {
  let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
  dispatch_async(dispatch_get_global_queue(priority, 0)) {
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.startGPS()
    while (!appDelegate.isLocationFixed()) {
      sleep(1)
    }
    dispatch_async(dispatch_get_main_queue()) {
      return appDelegate.getLocation()
    }
  }
}

but now this line return appDelegate.getLocation() brings me the error: 但是现在这行return appDelegate.getLocation()给我带来了错误:

unexpected non-void return value in void function void函数中意外的非无效返回值

I don't know too much about threads in Swift yet, could you help me with fixing this issue? 我对Swift线程还不太了解,您能帮我解决这个问题吗?

The problem is 问题是

dispatch_async(dispatch_get_global_queue(priority, 0)) {

and

dispatch_async(dispatch_get_main_queue()) {

are actually creating closures/functions, so any code within them will relate to that function, not 实际上是在创建闭包/函数,因此其中的任何代码都将与该函数相关,而不是

func handleLocation() -> CLLocation {

If you're doing an asynchronous operation within a function, you can't really have a return statement after the asynchronous operation is completed. 如果要在函数内执行异步操作,则在异步操作完成之后就不能真正拥有return语句。 Instead, you should use a completion handler in your function. 相反,您应该在函数中使用完成处理程序。 eg: 例如:

func aSyncFunction(completionHandler: (AnyObject) -> ()) {

    //do async opporation

    completionHandler("finished") // call the completion block when finished
}

Here's how I would implement it for your use case: 这是我为您的用例实现的方式:

func handleLocation(completionBlock: (CLLocation?) -> ()) {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

        guard let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate else {
            dispatch_async(dispatch_get_main_queue()) {
                completionBlock(nil)
            }
            return
        }
        appDelegate.startGPS()
        while (!appDelegate.isLocationFixed()) {
            sleep(1)
        }
        dispatch_async(dispatch_get_main_queue()) {
            completionBlock(appDelegate.getLocation())
        }
    }
}

example usage: 用法示例:

handleLocation { (location: CLLocation?) in
    if let location = location {
         //use valid location
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM