我正在尝试通过调用UITableView
更新.reloadData()
中的单元格,但它会在进程完成之前重新加载数据,因此不会真正更新任何内容,因为它从中获取数据的数组仍为空。我编写代码的方式是它产生一堆API调用,每个调用都是Swift Operation
。 OperationQueue
执行这些操作。现在需要做的是完成所有任务后调用self.tableView.reloadData()
。我已经尝试将它放在一个操作的完成块中,但它不是主线程,因此不会执行。
任何帮助将不胜感激。
编辑:我已经尝试使用OperationQueue
将OperationQueue.main
的线程更改为主线程并添加在包含{{1的所有其他操作完成后运行的最终操作}}。虽然这允许我重新加载self.tableView.reloadData()
,但它会导致UI滞后。 (我在UITable
中进行刷新,使得主线程使用明显。)
示例代码:
UITableView
答案 0 :(得分:1)
有两种可能的方法:
创建一个新的操作,当其他所有操作完成后,您要执行该操作,我将调用"完成操作"。然后,每次创建现有的单个操作之一时,将该操作作为依赖项添加到"完成操作"。然后,当您完成添加所有单个操作(并将每个操作作为依赖项添加到"完成操作)后,将完成操作添加到主队列。在所有其他单独的操作完成之前,它不会被激活。
例如:
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 4
let completionOperation = BlockOperation {
print("done")
}
for _ in 0 ..< 10 {
let operation = ...
completionOperation.addDependency(operation)
queue.addOperation(operation)
}
OperationQueue.main.addOperation(completionOperation)
请注意,这假设您已仔细创建了您的操作,因此操作无法完成,直到各个操作中的任务完成为止。值得注意的是,如果您的操作正在启动一个本身就是异步任务(例如网络请求)的任务,请确保将Operation
子类定义为&#34;异步&#34;操作(isAsynchronous
返回true
)并确保完成后正确执行isFinished
/ isExecuting
KVO。
另一种方法是使用调度组。每次创建一个单独的操作时,enter
组(不在操作本身,而是在创建这些操作并将其添加到操作队列中时)。然后,作为您个人操作中的最后一项任务,leave
该组。然后,当您完成所有单个操作的添加后,您可以创建一个调度组notify
,您可以在主队列上进行调度。然后,当所有单个操作时,您的调度组通知块将触发。
例如:
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 4
let group = DispatchGroup()
for _ in 0 ..< 10 {
group.enter()
let operation = BlockOperation {
...
group.leave()
}
queue.addOperation(operation)
}
group.notify(queue: .main) {
print("done")
}
我倾向于选项1(保持在操作队列范例内),但这两种方法都有效。
答案 1 :(得分:0)
从完成块中,您可以使用Grand Central Dispatch在主线程上执行另一个块。使用
DispatchQueue.main.async {
self.tableView.reloadData()
// your other code here
}
答案 2 :(得分:-1)
使用DispatchGroup。
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
asyncTask1() {
dispatchGroup.leave()
}
asyncTask2() {
dispatchGroup.leave()
}
asyncTask3() {
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
//reload table
}
答案 3 :(得分:-1)
您可以使用完成处理程序示例:
func reloadData(completion: @scaping (completed: Bool)->Void) {
//your code
completion(true)
}
调用func
reloadData() {(completed : Bool) in
if completed {
tableView.reloadData()
}
}