我有一个运行异步函数的for-in
循环。当所有这些异步函数都完成后,我想调用观察者然后重新加载UITableView
。基本上,这就是我所拥有的:
var reloadTable:Bool = false {
didSet {
if reloadTable {
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) { // 1
dispatch_async(dispatch_get_main_queue()) { // 2
self.tableView.reloadData() // 3
}
}
}
}
}
func arrayContains(array:[[String:AnyObject]]) {
for song in array {
// async function with completion block({
self.reloadTable = true
})
}
reloadTable = false
}
问题是tableView
在for循环的每次迭代后重新加载。我希望只有在阵列中迭代完所有歌曲后才会调用它。原因是,我异步获取UITableView
中的歌曲的专辑封面,但是他们正在按顺序下载。所以我需要将它们附加到特定索引的数组,然后重新加载表视图。有什么建议吗?
答案 0 :(得分:3)
GCD's dispatch group可用于此目的。
func arrayContains(array:[[String:AnyObject]]) {
var downloadGroup = dispatch_group_create()
for song in array {
dispatch_group_enter(downloadGroup)
// async function with completion block({
dispatch_group_leave(downloadGroup)
})
}
dispatch_group_notify(downloadGroup, dispatch_get_main_queue()) {
self.reloadTable = true //Take care of cyclic reference here.
}
}
}
答案 1 :(得分:0)
添加计数如何表示加载/加载:
var loadingCount = 0
func arrayContains(array:[[String:AnyObject]]) {
for song in array {
self.loadingCount += 1 // Increase 1 when loading
// in the completion block({
self.loadingCount -= 1 // Decrease 1 when loaded
if(loadingCount == 0){
self.reloadTable = true
}
})
}
}
// Or you want to be safe, set the total before the loop
func arrayContains(array:[[String:AnyObject]]) {
self.loadingCount = count(array)
for song in array {
// in the completion block({
self.loadingCount -= 1 // Decrease 1 when loaded
if(loadingCount == 0){
self.reloadTable = true
}
})
}
}