【发布时间】:2015-02-06 21:11:31
【问题描述】:
我正在尝试使用CloudKit 制作一个简单的基于表格的应用程序,它允许您深入查找有关特定项目的更多信息。假设我的应用显示了位于主题公园内的商店目录,按公园的各个部分划分。
在我的初始表格视图中,我能够获得 ThemeParks 的列表。点击 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)
}
})
}
问题是,getSectionsFromCloud() 在所有 getShopsFromCloud() 调用之前完成。因此,如果我在完成处理程序中为 getSectionsFromCloud 重新加载表视图,它将不会显示商店。但是,如果我在completionHandler 中为getShopsFromCloud 重新加载表视图,则每次执行查询时(每个部分执行一次),numberOfRowsInSection 也会为每个部分调用一次。所以如果我的numberOfRowsInSection是这样的:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.shops[section].count
}
...我收到“致命错误:数组索引超出范围”错误,因为第一个商店数组已下载,但随后为第二个数组调用 numberOfRowsInSection,但该数组尚不存在。那么我如何知道getShopsFromCloud() 何时结束以及我在世界上的哪个位置拨打tableView.reloadData() 电话?
【问题讨论】:
-
好吧,你需要看看 GCD - Using Dispatch Groups。
-
感谢您为我指明正确的方向!
-
查看本教程以了解其工作原理:raywenderlich.com/79150/…。在您的情况下,您需要创建一个将下载部分的调度组,然后在完成后,您将使用行更新部分并重新加载表视图。
标签: ios uitableview swift cloudkit