ios - Swift 闭包 - 关于值分配的代码执行顺序
问题描述
我想详细了解在完成处理程序中处理数据时的正确执行顺序。我的 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 已经被分配了返回值,不是吗?
解决方案
以下是您的相关功能的摘要:
...
context.perform {
entities = try! fetch.execute()
completion(entities)
}
return entities
斯威夫特是这样看的:
- 调用这个
context.perform
函数 - 称呼
return entities
- 处理
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
}
推荐阅读
- swift - 我无法使用 PHPhotoLibrary 删除带有照片的自定义相册
- r - R 函数式编程:使用应用族计算高斯过程的核矩阵
- sqlite - 从 SAP BO 到 Spark Thrift Server 的 SYNTHJOIN 查询
- mercurial - 如何将 mercurial strip/histedit/rebase 备份转换为补丁文件?
- symfony - 在 Codeception 测试上运行 Symfony 控制台命令不会在 db 上持久更改,不会引发错误
- ruby - 使用 Bundler 1.17.2 运行 Jekyll 4.0.0 时出现未处理的异常
- google-cloud-platform - 无需停机即可将实时域切换到 Google Cloud Run
- python - 按标签的决策树
- mysql - Homebrew sql@5.7 服务器退出而不更新 Catalina 中的 PID 文件
- python - 如何将默认的 Django 引擎数据库从 db.sqlite3 更改为填充了测试数据的 mysql 数据库?