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

时间:2018-09-27 20:27:16

标签: ios swift completionhandler

我想详细了解在完成处理程序中处理数据时执行的正确顺序。我的Event类上具有以下函数定义:

@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应该已经被分配了返回值,不是吗?

1 个答案:

答案 0 :(得分:1)

以下是您所讨论功能的摘要:

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

Swift会这样看:

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

由于顺序,它只返回值并认为其工作已完成。假设它处于范围内,您的关闭可能会完成,但是除此之外什么也没有。

最简单的方法是更改​​您的功能:

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

收件人:

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

这里的区别是删除了[Event]返回。

然后,在函数内部删除return entities行。

您现在有了一个异步函数,因此无论调用什么,都必须对[Event]值使用闭包。

self.events = Event.getEventsFromAPI()变为:

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