Swift 闭包 - 关于赋值的代码执行顺序

Swift closures - order of code execution in regards to value assignment

我想详细了解在完成处理程序中处理数据时正确的执行顺序。我的事件 class:

有以下函数定义
@nonobjc public class func fetchEvents(completion: @escaping ([Event]) -> () = { _ in }) -> [Event] {
    let fetch = self.fetchEventRequest()

    var entities: [Event] = []
    context.perform {
        entities = try! fetch.execute()
        completion(entities)
    }
    return entities
}

然后我从我的视图控制器中调用上述函数:

events = MyEvents.fetchEvents() { entities in
        if (entities.count == 0) {
            self.events = Event.getEventsFromAPI()
        } 
        print(events.count) - // returns 0 at this point
        self.eventsTableView.reloadData()
    }

调用 self.eventsTableView.reloadData() 后,我的 events 变量仍然是空的。我假设由于完成处理程序是在函数内的代码成功执行后执行的,所以 events var 已经被分配了返回值,不是吗?

以下是您的相关函数的摘要:

...
context.perform {
    entities = try! fetch.execute()
    completion(entities)
}
return entities

Swift 是这样看的:

  1. 调用此 context.perform 函数
  2. 致电return entities
  3. 在闭包中处理 context.perform 的输出

由于顺序,它只是 return 值并认为它的工作已经完成。假设它在范围内,您的关闭可能会完成,但除此之外没有任何结果。

最简单的方法是更改​​您的函数:

@nonobjc public class func fetchEvents(completion: @escaping ([Event]) -> () = { _ in }) -> [Event]

至:

@nonobjc public class func fetchEvents(completion: @escaping ([Event]) -> () = { _ in })

这里的区别是删除了 [Event] return.

然后,在您的函数中删除 return entities 行。

你现在有了一个异步函数,所以无论你用什么来调用它,都必须为 [Event] 值使用一个闭包。

self.events = Event.getEventsFromAPI() 变成这样:

Event.getEventsFromAPI() = { [weak self] events in
    self?.events = events
}