我有多个 API 调用将在获取结果时更新 uitableview。UI 需要在 API 提供数据时更新。所有 API 调用都是异步的。数据必须以正确的顺序填充。API0 应该更新第 0 节,API1 应该更新第 1 节,依此类推。
我已经能够使用 2 个 API 来实现这一点,但是当我使用第 3 个 API 时,我会遇到崩溃。
请在下面找到我的代码:
@IBOutlet weak var myTableView: UITableView!
var myDataSource: myTableDataSource!
var initialLoad = true
var tablD = [Int : [Any]]()
let queue = DispatchQueue(
label: "com.affluvar.multipleAPI.MyQueue", // 1
attributes: .concurrent)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myTableView.tableFooterView = UIView()
API0()
API1()
API2()
}
//MARK: API methods
func API0(){
queue.async {
print("queue THREAD0")
getData(offset: 0,limit: 10){
(finalArray) in
print("IN FIRST")
for rest in finalArray{
print(rest.name)
}
self.queue.sync {
self.tablD.updateValue(finalArray, forKey: 0)
self.myDataSource = myTableDataSource(data: self.tablD)
print("SYNC DATASOURCE UPDATED 0")
DispatchQueue.main.async {
if self.initialLoad == true{
self.initialLoad = false
self.myTableView.dataSource = self.myDataSource
print("TABLE RELOADING INITIAL ")
self.myTableView.reloadData()
}
}
self.saveData(data: finalArray, section: 0)
}
}
}
}
func API1(){
queue.async{
print("queue THREAD1 ")
getData(offset: 10,limit: 12){
(finalArray1) in
print("IN SECOND ")
for rest in finalArray1{
print(rest.name)
}
self.queue.sync{
self.tablD.updateValue(finalArray1, forKey: 1)
self.myDataSource = myTableDataSource(data: self.tablD)
print("SYNC DATASOURCE UPDATED 1")
DispatchQueue.main.async {
if self.initialLoad == true{
self.initialLoad = false
self.myTableView.dataSource = self.myDataSource
print("TABLE RELOADING INITIAL ")
self.myTableView.reloadData()
}
}
self.saveData(data: finalArray1, section: 1)
}
}
}
}
func API2(){
queue.async{
print("queue THREAD2")
getData(offset: 20,limit: 12){
(finalArray1) in
print("IN third")
for rest in finalArray1{
print(rest.name)
}
self.queue.sync{
self.tablD.updateValue(finalArray1, forKey: 2)
self.myDataSource = myTableDataSource(data: self.tablD)
print("SYNC DATASOURCE UPDATED 2")
DispatchQueue.main.async {
if self.initialLoad == true{
self.initialLoad = false
self.myTableView.dataSource = self.myDataSource
print("TABLE RELOADING INITIAL ")
self.myTableView.reloadData()
}
}
self.saveData(data: finalArray1, section: 2)
}
}
}
}
func saveData(data:[userModel], section: Int){
print("queue THREAD barrier ", section)
//print("table datasrc entry:", self.myTableView.dataSource ?? "nil")
DispatchQueue.main.sync {
print("In else ", section)
print("sections before IN ELSE",self.myTableView.numberOfSections)
self.myTableView.dataSource = self.myDataSource
//self.myTableView.reloadData()
//self.myTableView.beginUpdates()
print("reloading section number:", section)
self.myTableView.reloadSections([section], with: .automatic)
print("sections AFTER in ELSE",self.myTableView.numberOfSections)
//self.myTableView.endUpdates()
}
print("CONTINUING QUEUE WORK")
}
以上是我的 viewController 代码。
这里的错误是->
2018-08-01 16:13:14.381174+0530 docAnywhere[4299:118229] *** Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UITableView.m:13456 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource is not set'
表数据源类 ->>
class myTableDataSource: NSObject, UITableViewDataSource{
var userData = [Any]()
var tableData = [[Any]]()
var tablD = [Int : [Any]]()
init(data: [Int : [Any]]) {
tablD = data
}
//MARK: Table methods
func numberOfSections(in tableView: UITableView) -> Int {
//print("sections:", tablD.count)
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("reload in progress")
if let rows = tablD[section] as? [Any]{
return rows.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "usersCell") as! usersCell
let rowData = tablD[indexPath.section] as! [Any]
let thisUser = rowData[indexPath.row] as? userModel// userData[indexPath.row] as? userModel
cell.userName?.text = thisUser?.name ?? ""
print("cell no", thisUser?.name ?? "", "at", indexPath.section, indexPath.row)
if (indexPath.row == (rowData.count - 1)) {
print("LAST CELL RELOAD COMPLETE HERE", indexPath.section)
}
return cell
}
}
有时错误是这样的:-
2018-08-01 16:47:53.467219+0530 docAnywhere[6084:147469] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete section 0, but there are only 0 sections before the update'
注意:: 在 2 个 API 调用和调度组不能使用的情况下它工作正常,因为 UI 需要在任何 API 调用完成并且数据可用时立即更新。多个数组或数据源不能用于多个 API。