我正在尝试使用CloudKit
制作一个简单的基于表格的应用程序,该应用程序允许您深入查找有关特定项目的更多信息。假设我的应用程序显示了位于主题公园内的商店目录,并按园区划分。嵌套的CloudKit查询和UITableView
在我的初始表格视图中,我能够获得ThemeParks列表。点击ThemePark可深入到另一个表格视图,该表格视图具有园区每个部分的标题标题。我能够查询与选定的ThemePark匹配的CKReference
的部分。当我尝试获得与每个部分匹配的商店时,就会出现问题。我不知道如何等待商店全部下载,然后重新加载表格视图。下面是从我的视图控制器一些示例代码:
func getSectionsFromCloud() {
let cloudContainer = CKContainer.defaultContainer()
let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase
let recordToMatch = CKReference(recordID: themePark.recordID, action: CKReferenceAction.DeleteSelf)
let predicate = NSPredicate(format: "themeParkOwner == %@", recordToMatch)
let query = CKQuery(recordType: "ThemeParkSection", predicate: predicate)
let sort = NSSortDescriptor(key: "name", ascending: true)
query.sortDescriptors = [sort]
self.publicDatabase.performQuery(query, inZoneWithID: nil, completionHandler: {
results, error in
if error == nil {
println("Successfully retrieved sections")
self.sections = results as [CKRecord]
for section in self.sections {
self.getShopsFromCloud(section)
}
} else {
println(error)
}
})
}
这里是我的getShopsFromCloud
功能:
func getShopsFromCloud(record:CKRecord) {
let cloudContainer = CKContainer.defaultContainer()
let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase
let recordToMatch = CKReference(recordID: record.recordID, action:CKReferenceAction.DeleteSelf)
let predicate = NSPredicate(format: "sectionOwner == %@", recordToMatch)
let query = CKQuery(recordType: "Shop", predicate: predicate)
self.publicDatabase.performQuery(query, inZoneWithID: nil, completionHandler: {
results, error in
if error == nil {
println("Successfully retrieved shops.")
self.shops.append(results as [CKRecord])
} else {
println(error)
}
})
}
的问题是,之前的所有getShopsFromCloud()
电话getSectionsFromCloud()
完成。因此,如果我重新加载getSectionsFromCloud的completionHandler中的表视图,它将不会显示商店。但是,如果我重新加载completionHandler
中的表格视图getShopsFromCloud
,每次执行查询(每个部分一次),numberOfRowsInSection
也会为每个部分调用一次。所以,如果我的numberOfRowsInSection
是这样的:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.shops[section].count
}
...我得到一个“致命的错误:数组索引超出范围”错误,因为商店的第一阵列被下载,但随后numberOfRowsInSection
被称为第二阵列,这还没有。那么我怎样才能知道getShopsFromCloud()
何时完成,以及我在世界的哪个位置拨打tableView.reloadData()
电话?
那么,你需要看看GCD - 使用调度组。 – Shmidt 2015-02-06 21:22:54
感谢您指点我正确的方向! – 2015-02-07 05:27:18
查看本教程以了解其工作原理:http://www.raywenderlich.com/79150/grand-central-dispatch-tutorial-swift-part-2。在你的情况下,你需要创建一个将下载段的调度组,然后当它完成时,你将用行更新段并重新加载表视图。 – Shmidt 2015-02-07 09:21:14