如何重新加载的UITableView时OperationsQueue与所有操作完成[关闭]

问题描述 投票:3回答:4

我试图通过调用UITableView以更新.reloadData()的细胞,但过程中完成,因此没有真正更新任何事情,因为它获得的数据来自仍然是空数组之前重新加载数据。我有构造的代码的方式是,它使得一大堆的分别是雨燕Operation API调用。一个OperationQueue执行这些操作。当所有的任务都完成它,例如呼叫self.tableView.reloadData()需要什么,现在发生的是。我试图把它在一个操作的结束块,但这不是主线程,因此不会执行。

任何帮助,将不胜感激。

编辑:我已经尝试使用OperationQueue,加入后所有其他操作完成包含OperationQueue.main正在运行最终的操作改变self.tableView.reloadData()的线程主线程。虽然这让我重新加载它使UI滞后于UITable。 (我有一个拉在这使得主线程使用明显UITableView刷新。)

示例代码:

let operation1 = BlockOperation {
//Gets Data from server & waits until task is complete before ending
}

let operation2 = BlockOperation {
//Parse JSON
}

let updateOperation = BlockOperation {
    self.tableView.reloadData()
    //Throws a "UITableView.reloadData() must be used from main thread only"
}

operation2.addDependency(operation1)
updateOperation.addDependency(operation2)

let queue = OperationQueue()
queue.addOperation(operation1)
queue.addOperation(operation2)
queue.addOperation(completionOperation)
swift uitableview nsoperationqueue nsoperation
4个回答
1
投票

有两种可能的方法:

  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子类是一个“同步”操作(isAsynchronous返回true),并确保它在isFinished / isExecuting志愿正确完成时。
  2. 另一种方法是使用一个调度组。您建立个性化的操作之一,每次,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(停留在操作队列范式内),但是这两种方法是可行的。


0
投票

从完成块,你可以使用大中央调度主线程上执行另一个块。采用

DispatchQueue.main.async {
    self.tableView.reloadData()
    // your other code here
}

-1
投票

你可以使用一个完成处理程序例如:

func reloadData(completion: @scaping (completed: Bool)->Void) {
     //your code
     completion(true)
}

调用FUNC

reloadData() {(completed : Bool) in
    if completed {
      tableView.reloadData()
    }    
}

-1
投票

使用DispatchGroup。

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()

asyncTask1() { dispatchGroup.leave() }

asyncTask2() { dispatchGroup.leave() }

asyncTask3() { dispatchGroup.leave() }

dispatchGroup.notify(queue: .main) {
//reload table }

© www.soinside.com 2019 - 2024. All rights reserved.