Swift 意外延迟行为

Swift 意外延迟行为,swift,swift2,Swift,Swift2,我有一个异步处理的函数: func something(completion: [Something] -> Void) { dispatch_async(queue) { ... dispatch_async(dispatch_get_main_queue()) { completion(something) } } } 我认为明智的做法是使用defer来保证每次调用completion,因此我尝试了以下方法: func something(

我有一个异步处理的函数:

func something(completion: [Something] -> Void) {
  dispatch_async(queue) {
    ...
    dispatch_async(dispatch_get_main_queue()) {
      completion(something)
    }
  }
}
我认为明智的做法是使用
defer
来保证每次调用
completion
,因此我尝试了以下方法:

func something(completion: [Something] -> Void) {
  dispatch_async(queue) {
    ...
    defer {
      dispatch_async(dispatch_get_main_queue()) {
        completion(something)
      }
    }
  }
}
工作顺利。然后我尝试在总是失败的异步调度中使用
guard
语句,以查看
defer
是否会激活。它没有:

func something(completion: [Something] -> Void) {
  dispatch_async(queue) {
    ...
    guard let shouldFail = ... else { return }
    defer {
      dispatch_async(dispatch_get_main_queue()) {
        completion(something)
      }
    }
  }
}

defer
将不会被调用。为什么?

因为您在返回后正在使用
延迟。编译器不知道您指定了
defer
指令(因为它已经返回,并且在该点上没有看到任何defer指令,所以下一行不会启动)。如果您将
延迟{}
移动到防护装置之前,那么它将被调用。

防护装置将在到达
延迟
之前返回。试着用另一种方法:

func something(completion: [Something] -> Void) {
  dispatch_async(queue) {
    ...
    defer {
      dispatch_async(dispatch_get_main_queue()) {
        completion(something)
      }
    }
    guard let shouldFail = ... else { return }
  }
}