CloudKit-具有依赖项的CKQueryOperation [英] CloudKit - CKQueryOperation with dependency

查看:154
本文介绍了CloudKit-具有依赖项的CKQueryOperation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用CloudKit,所以请耐心等待。

I'm just beginning working with CloudKit, so bear with me.

背景信息

在WWDC 2015上,苹果发表了关于CloudKit的演讲 https: //developer.apple.com/videos/wwdc/2015/?id=715

At WWDC 2015, apple gave a talk about CloudKit https://developer.apple.com/videos/wwdc/2015/?id=715

在此演讲中,他们警告不要创建链接查询,而是建议这种策略:

In this talk, they warn against creating chaining queries and instead recommend this tactic:

let firstFetch = CKFetchRecordsOperation(...)
let secondFetch = CKFetchRecordsOperation(...)
...
secondFetch.addDependency(firstFetch)

letQueue = NSOperationQueue()
queue.addOperations([firstFetch, secondFetch], waitUntilFinished: false)

示例结构

测试项目数据库包含宠物及其主人,它看起来像这样:

The test project database contains pets and their owners, it looks like this:

|Pets               |   |Owners     |
|-name              |   |-firstName |
|-birthdate         |   |-lastName  |
|-owner (Reference) |   |           |

我的问题

我正在尝试查找所有属于主人的宠物,并且我担心自己正在创建苹果警告的链条。参见下文,了解两种执行相同操作但有两种方法的方法。哪个更正确或都错?我感觉我在做同样的事情,只是使用完成块。

I am trying to find all pets that belong to an owner, and I'm worried I'm creating the chain apple warns against. See below for two methods that do the same thing, but two ways. Which is more correct or are both wrong? I feel like I'm doing the same thing but just using completion blocks instead.

我对如何更改otherSearchBtnClick:使用依赖感到困惑。 / strong>我需要在哪里添加

I'm confused about how to change otherSearchBtnClick: to use dependency. Where would I need to add

ownerQueryOp.addDependency(queryOp)

in otherSearchBtnClick:?

in otherSearchBtnClick:?

@IBAction func searchBtnClick(sender: AnyObject) {
    var petString = ""
    let container = CKContainer.defaultContainer()
    let publicDatabase = container.publicCloudDatabase
    let privateDatabase = container.privateCloudDatabase

    let predicate = NSPredicate(format: "lastName == '\(ownerLastNameTxt.text)'")
    let ckQuery = CKQuery(recordType: "Owner", predicate: predicate)
    publicDatabase.performQuery(ckQuery, inZoneWithID: nil) {
        record, error in
        if error != nil {
            println(error.localizedDescription)
        } else {
            if record != nil {
                for owner in record {
                    let myRecord = owner as! CKRecord
                    let myReference = CKReference(record: myRecord, action: CKReferenceAction.None)

                    let myPredicate = NSPredicate(format: "owner == %@", myReference)
                    let petQuery = CKQuery(recordType: "Pet", predicate: myPredicate)
                    publicDatabase.performQuery(petQuery, inZoneWithID: nil) {
                        record, error in
                        if error != nil {
                            println(error.localizedDescription)
                        } else {
                            if record != nil {
                                for pet in record {
                                    println(pet.objectForKey("name") as! String)

                                }

                            }
                        }
                    }
                }
            }
        }
    }
}

@IBAction func otherSearchBtnClick (sender: AnyObject) {
    let container = CKContainer.defaultContainer()
    let publicDatabase = container.publicCloudDatabase
    let privateDatabase = container.privateCloudDatabase

    let queue = NSOperationQueue()
    let petPredicate = NSPredicate(format: "lastName == '\(ownerLastNameTxt.text)'")
    let petQuery = CKQuery(recordType: "Owner", predicate: petPredicate)
    let queryOp = CKQueryOperation(query: petQuery)
    queryOp.recordFetchedBlock = { (record: CKRecord!) in
        println("recordFetchedBlock: \(record)")
        self.matchingOwners.append(record)
    }

    queryOp.queryCompletionBlock = { (cursor: CKQueryCursor!, error: NSError!) in
        if error != nil {
            println(error.localizedDescription)
        } else {
            println("queryCompletionBlock: \(cursor)")
            println("ALL RECORDS ARE: \(self.matchingOwners)")
            for owner in self.matchingOwners {
                let ownerReference = CKReference(record: owner, action: CKReferenceAction.None)
                let ownerPredicate = NSPredicate(format: "owner == %@", ownerReference)
                let ownerQuery = CKQuery(recordType: "Pet", predicate: ownerPredicate)
                let ownerQueryOp =  CKQueryOperation(query: ownerQuery)
                ownerQueryOp.recordFetchedBlock = { (record: CKRecord!) in
                    println("recordFetchedBlock (pet values): \(record)")
                    self.matchingPets.append(record)
                }
                ownerQueryOp.queryCompletionBlock = { (cursor: CKQueryCursor!, error: NSError!) in
                    if error != nil {
                        println(error.localizedDescription)
                    } else {
                        println("queryCompletionBlock (pet values)")
                        for pet in self.matchingPets {
                            println(pet.objectForKey("name") as! String)
                        }
                    }
                }
            publicDatabase.addOperation(ownerQueryOp)
            }
        }


    }
    publicDatabase.addOperation(queryOp)
}


推荐答案

理论上,您可以有多个所有者,因此可以有多个依赖关系。同样,内部查询将在外部查询已执行之后创建。创建一个依赖关系将为时已晚。在您的情况下,将内部查询的执行强制到这样一个单独的队列可能更容易:

in theory you could have multiple owners and therefore multiple dependencies. Also the inner queries will be created after the outer query is already executed. You will be too late to create a dependency. In your case it's probably easier to force the execution of the inner queries to a separate queue like this:

if record != nil {
    for owner in record {
        NSOperationQueue.mainQueue().addOperationWithBlock {

这样,您将确保每个内部查询都将在新的队列上执行,同时确保父查询可以完成。

This way you will make sure that every inner query will be executed on a new queue and in the mean time that parent query can finish.

还有其他事情:代码清理器,最好将for循环内的所有代码都放在单独的函数中,并以CKReference作为参数。

Something else: to make your code cleaner, it would be better if all the code inside the for loop was in a separate function with a CKReference as a parameter.

这篇关于CloudKit-具有依赖项的CKQueryOperation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆