比方说,我有两个类:一个类代表我执行HTTP GET请求的数据库。
func getObjects(completion: (([Object]) -> Void)?) {
guard let url = // ...
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
DispatchQueue.main.async {
if let error = error {
fatalError("Dispatching main queue failed: \(error)")
} else if let data = data {
let decoder = JSONDecoder()
do {
let objects = try decoder.decode([Object].self, from: data)
completion?(object)
} // ...
// ...
}
task.resume()
}
将相应的结果对象数组传递给另一个类的UIViewController。因为我基于不同的配置对象实例化了多个数据库,所以我想显示按UITableView节排序的结果。
func load(then: (([(DatabaseConfig?, [Object])]) -> Void)) {
var allObjects: [(DatabaseConfig?, [Object])] = [(nil, [])]
Storage.loadDatabaseConfigs(completion: { configs in
self.configs = configs
})
for config in self.configs {
var objectSection: (DatabaseConfig?, [Object]) = (nil, [])
let database = Database.init(config: config)
objectSection.0 = config
database.getObjects(completion: { objects in
objectSection.1.append(objects)
})
allObjects.append(allObjectsInSection)
}
then(allObjects)
}
加载和“格式化”有效。
我在load(then:)
中调用viewWillAppear()
函数,在这里将结果传递给类数组,该类数组包含TableView的所有最终条目。然后,我尝试重新加载数据。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.load(then: { objects in
self.allObjects = objects
self.tableView.reloadData()
})
}
我知道GET请求需要时间,所以我的问题是:如何或在何处重新加载UITableView?我显然需要确定GET请求已执行成功,然后重新加载。我已经尝试调用DispatchQueue.main.async
进行重新加载,但这没有用。
答案 0 :(得分:2)
由于您发出了多个请求,因此您确实不希望在所有请求完成之前调用then
闭包。您可能为此使用DispatchGroup
。
func load(then: (([(DatabaseConfig?, [Object])]) -> Void)) {
var allObjects: [(DatabaseConfig?, [Object])] = [(nil, [])]
Storage.loadDatabaseConfigs(completion: { configs in
self.configs = configs
let dispatchGroup = DispatchGroup()
for config in self.configs {
dispatchGroup.enter()
var objectSection: (DatabaseConfig?, [Object]) = (nil, [])
let database = Database.init(config: config)
objectSection.0 = config
database.getObjects(completion: { objects in
objectSection.1.append(objects)
dispatchGroup.leave()
})
allObjects.append(allObjectsInSection)
}
dispatchGroup.notify(queue: .main) {
then(allObjects)
}
})
}
编辑:如@Macistador所述,loadDatabaseConfigs是异步的,因此应在该函数的completion
回调中进行数据库调用。