我的应用程序通过 FileManager 为 UITableView 中的每个单元格获取数据。单元格需要来自需要打开 UIDocument 对象的文件的数据。但是,打开完成处理程序中的代码似乎无法预测地执行,因此单元格不会按照我希望的顺序显示。
我该如何解决这个问题?如果有人提供任何线索,我将不胜感激。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
fetchCellsData()
}
func fetchCellsData() {
do {
let files = getUrlsOfFiles() //files in a certain order
for file in files {
let document = MyDocument(fileURL: file) //MyDocument subclassing UIDocument
//open to get data for cell
document.open { (success) in
if !success {
print("File not open at %@", file)
return
}
let data = populateCellData(document.fileInfo)
self.cellsData.append(data)
self.tableView.reloadData()
/// tried below also
// DispatchQueue.main.async {
// self.cellsData.append(data)
// self.tableView.reloadData()
// }
}
document.close(completionHandler: nil)
}
} catch {
print(error)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyCell
let fileInfo = cellsData[indexPath.row].fileInfo
//assign fileInfo into MyCell property
return cell
}
我希望单元格按照"file"的顺序呈现,但是,似乎顺序有点不可预测,假设这是因为“cellForRowAt”在知道完整的“cellsData”集之前被调用'.
最佳答案
来自 UIdocument
上的 Apple 文档。 Apple doc :
open(completionHandler:)
Opens a document asynchronously.
这意味着即使您以正确的顺序触发 document.open
,也无法保证 completionHandler
序列将以相同的顺序,这就是顺序的原因是不可预测的。
但是,您知道它们最终都会完成。
你可以做的是:
1 - 将打开文档中的所有数据放入另一个列表
2 - 根据您的需要排序
此列表
3 - 将此列表放入 cellsData
(我假设它已绑定(bind)到您的 tableViesDatasource)
var allDatas: [/*your data type*/] = []
...
do {
// reset allDatas
allDatas = []
let files = getUrlsOfFiles()
for file in files {
let document = MyDocument(fileURL: file)
document.open { (success) in
if !success {
print("File not open at %@", file)
return
}
let data = populateCellData(document.fileInfo)
self.allDatas.append(data) // "buffer" list
self.tableView.reloadData()
}
document.close(completionHandler: nil)
}
} catch { ...
然后将 cellsData
更改为计算属性,如下所示:
var cellsData: [/*your data type*/] {
get {
return allDatas.order( /* order in accordance to your needs */ )
}
}
这样,每次添加新数据时,列表在重新显示之前都是有序的。
讨论
这是关于代码状态的更简单解决方案,但这可能不是总体首选解决方案。例如,在您的代码中,您每次添加新值时都会重新加载您的 tableview,因为您知道之后会添加更多数据,而这并没有得到优化。
我建议你阅读Dispatch Group,这是一种等待你触发的所有异步操作完成后再执行某些操作(例如在这种情况下重新加载你的tableview)的方法(阅读: Raywenderlich tuts )
关于ios - 从 UIDocument 获取单元格数据时,如何确保 UITableView 中显示的列表顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57583814/