1

performQuery另一个内部performQuery被调用。两者的recordType论点相同,但predicates 不同。

第二performQuery永远不会返回,应用程序只是运行并等待 CloudKit 响应。

伪代码是这样的:

publicDatabase.performQuery(CKQuery(recordType: recordTypeSrc, predicate: predicate), inZoneWithID: nil, completionHandler: {records, error in

    if error == nil {

        //.. problem is not name collision or reusing the same parameter, coming codepart is called though other methods

        publicDatabase.performQuery(CKQuery(recordType: recordTypeSrc, predicate: predicate2), inZoneWithID: nil, completionHandler: {records, error in

            //THIS LINE WILL NEVER GET REACHED

            if error == nil {

            } else {
                println(error.localizedDescription)
            }
            dispatch_semaphore_signal(sema2)
        })
        dispatch_semaphore_wait(sema2, DISPATCH_TIME_FOREVER)

        //..

    } else {
        println(error.localizedDescription)
    }
    dispatch_semaphore_signal(sema)
})
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
4

2 回答 2

0

死锁是这样修复的:内部查询在外部查询之后移动。两个信号量都保留了。外部完成处理程序在内部完成处理程序启动之前完成。从 CloudKit 返回的记录存储在本地变量中。

var records: [AnyObject]! = []
publicDatabase.performQuery(CKQuery(recordType: recordTypeSrc, predicate: predicate), inZoneWithID: nil, completionHandler: {records2, error in

    if error == nil {
        records = records2
    } else {
        println(error.localizedDescription)
    }
    dispatch_semaphore_signal(sema)
})
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)

//HERE I can use records

var records3: [AnyObject]! = []
publicDatabase.performQuery(CKQuery(recordType: recordTypeSrc, predicate: predicate2), inZoneWithID: nil, completionHandler: {records4, error in

    if error == nil {
        records3 = records4
    } else {
        println(error.localizedDescription)
    }
    dispatch_semaphore_signal(sema2)
})
dispatch_semaphore_wait(sema2, DISPATCH_TIME_FOREVER)

//HERE I can use records3 too
于 2014-10-11T14:54:23.370 回答
0

它看起来像一个信号量线程问题。您正在重用 sama 参数。最后一个 dispatch_semaphore_signal 必须移到 else 的上方。那么第一个dispatch_semaphore_wait就可以完全去掉了。所以它会是这样的:

publicDatabase.performQuery(CKQuery(recordType: recordTypeSrc, predicate: predicate), inZoneWithID: nil, completionHandler: {records, error in

    if error == nil {

        //.. problem is not name collision, it is nested though other blocks

        publicDatabase.performQuery(CKQuery(recordType: recordTypeSrc, predicate: predicate2), inZoneWithID: nil, completionHandler: {records, error in

            //THIS LINE WILL NEVER GET REACHED

            if error == nil {

            } else {
                println(error.localizedDescription)
            }
            dispatch_semaphore_signal(sema)
        })

        //..

    } else {
        println(error.localizedDescription)
        dispatch_semaphore_signal(sema)
    }
})
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
于 2014-10-10T09:16:55.143 回答