我的函数runsQueries
运行两个不同的查询。我需要完成这两个查询才能调用updateResults
函数。
完成任务的最佳方法是什么?我尝试了一些不同的东西,但到目前为止没有任何实际工作。
func runsQueries(){
var foundRecords = [CKRecords]()
let notified = dispatch_semaphore_create(0)
let group = dispatch_group_create()
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_group_async(group, queue) {
// query 1
let predicate1 = NSPredicate(format: "userID = %@", user1ID)
let cloudKitQuery1 = CKQuery(recordType: "Messages", predicate: predicate1)
publicDatabase.performQuery(cloudKitQuery1, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
if error != nil
{
print("-> cloudKitLoadMessage - userID1 error \(error)")
}
else
{
print("-> cloudKitLoadMessage - user1Done - message")
foundRecords.apend(messageRecords[0])
}
}
// query 2
let predicate2 = NSPredicate(format: "userID = %@", user2ID)
let cloudKitQuery2 = CKQuery(recordType: "Messages", predicate: predicate2)
publicDatabase.performQuery(cloudKitQuery2, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
if error != nil
{
print("-> cloudKitLoadMessage - userID2 error \(error)")
}
else
{
print("-> cloudKitLoadMessage - user2Done - message")
foundRecords.apend(messageRecords[0])
}
}
}
dispatch_group_notify(group, queue) {
// This block will be executed when all tasks are complete
print("All tasks complete")
dispatch_semaphore_signal(notified)
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
dispatch_semaphore_wait(notified, DISPATCH_TIME_FOREVER)
print("Semaphore done")
// only call updateResults when queries 1 and 2 are done
updateResults(foundRecords)
}
第二项功能
func updateResults(messageRecords: [CKrecord]){
// do something now that you got both messages
}
基于以下内容的一些想法:https://gist.github.com/nbhasin2/735cd80298b5d47852f2
答案 0 :(得分:2)
使用“Dispatch Gruop”并将两个查询放在两个不同的调度块中。
答案 1 :(得分:1)
可能有更优雅的解决方案,但我已经很好地使用了这种模式:
func runsQueries(){
var foundRecords = [CKRecords]()
var query1Finished = false
var query2Finished = false
let updateResultsIfNeeded {
if query1Finished && query2Finished {
updateResults(foundRecords)
}
}
// query 1
let predicate1 = NSPredicate(format: "userID = %@", user1ID)
let cloudKitQuery1 = CKQuery(recordType: "Messages", predicate: predicate1)
publicDatabase.performQuery(cloudKitQuery1, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
if error != nil
{
print("-> cloudKitLoadMessage - userID1 error \(error)")
}
else
{
print("-> cloudKitLoadMessage - user1Done - message")
foundRecords.apend(messageRecords[0])
}
query1Finished = true
updateResultsIfNeeded()
}
// query 2
let predicate2 = NSPredicate(format: "userID = %@", user2ID)
let cloudKitQuery2 = CKQuery(recordType: "Messages", predicate: predicate2)
publicDatabase.performQuery(cloudKitQuery2, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
if error != nil
{
print("-> cloudKitLoadMessage - userID2 error \(error)")
}
else
{
print("-> cloudKitLoadMessage - user2Done - message")
foundRecords.apend(messageRecords[0])
}
query2Finished = true
updateResultsIfNeeded()
}
}
答案 2 :(得分:1)
基于@christian mini的回答:
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// query 1
let predicate1 = NSPredicate(format: "userID = %@", user1ID)
let cloudKitQuery1 = CKQuery(recordType: "Messages", predicate: predicate1)
publicDatabase.performQuery(cloudKitQuery1, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
if error != nil
{
print("-> cloudKitLoadMessage - userID1 error \(error)")
}
else
{
print("-> cloudKitLoadMessage - user1Done - message")
foundRecords.apend(messageRecords[0])
}
}
});
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// query 2
let predicate2 = NSPredicate(format: "userID = %@", user2ID)
let cloudKitQuery2 = CKQuery(recordType: "Messages", predicate: predicate2)
publicDatabase.performQuery(cloudKitQuery2, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
if error != nil
{
print("-> cloudKitLoadMessage - userID2 error \(error)")
}
else
{
print("-> cloudKitLoadMessage - user2Done - message")
foundRecords.apend(messageRecords[0])
}
}
});
dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// only call updateResults when queries 1 and 2 are done
updateResults(foundRecords)
});
无论如何,您应该将查询块代码分离为一个函数。您的代码是重复的。
答案 3 :(得分:0)
感谢所有答案。我不得不最终混合了一些东西才能使它工作,因为这里值得分享。
我必须添加dispatch_group_enter
和dispatch_group_leave
才能在运行cloudkit查询时停止它。
这很奇怪,因为它只运行了dispatch_group_enter
和dispatch_group_leave
,如果只运行下面的代码:
let timeInterval = Double(arc4random_uniform(1000)) * 0.01
NSThread.sleepForTimeInterval(timeInterval)
还添加了for
循环以运行最多4个查询。尝试使用一系列ID创建一个for
并获得无限数量的查询,但它将ID排除在外,我按顺序需要它们。可以用字典试试。
let notified = dispatch_semaphore_create(0)
let group = dispatch_group_create()
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
for n in 1..<5 {
dispatch_group_async(group, queue) {
dispatch_group_enter(group)
print("nnnn \(n)")
var userID = String()
switch n {
case 1:
userID = user1ID
case 2:
userID = user2ID
case 3:
userID = user3ID
case 4:
userID = user4ID
default:
print("")
}
var predicate = NSPredicate()
predicate = NSPredicate(format: "userID = %@ AND chatRoomReference = %@", userID, roomReference)
let cloudKitQuery = CKQuery(recordType: "Messages", predicate: predicate)
let sort = NSSortDescriptor(key: "date", ascending: false)
cloudKitQuery.sortDescriptors = [sort]
publicDatabase.performQuery(cloudKitQuery, inZoneWithID: nil) { (messageRecords: [CKRecord]?, error: NSError?) in
// result in here
switch n {
case 1:
user1Dic = userDic
case 2:
user2Dic = userDic
case 3:
user3Dic = userDic
case 4:
user4Dic = userDic
default:
print("")
}
dispatch_group_leave(group)
}
}
}
dispatch_group_notify(group, queue) {
print("All tasks complete")
dispatch_semaphore_signal(notified)
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
print("All tasks dispatch_group_wait")
dispatch_semaphore_wait(notified, DISPATCH_TIME_FOREVER)
print("All tasks dispatch_semaphore_wait")
// that is when I return the results from all queries
updateResults(error: nil, user1Dic: user1Dic, user2Dic: user2Dic, user3Dic: user3Dic, user4Dic: user4Dic)