使用CloudKit的依赖异步请求

时间:2015-01-26 18:45:00

标签: ios icloud cloudkit

我正在构建一个使用CloudKit作为后端的应用程序。我有 ShoppingList 记录和 GroceryItem 记录。购物清单可以有许多杂货。我正在使用反向关系技术,这意味着杂货商品可以参考购物清单(父母)。

现在,我想显示购物清单中的杂货商品数量。这是我的实施:

-(void) getAllShoppingLists:(GetAllShoppingListsResult)getAllShoppingLists {

    CKQuery *query = [[CKQuery alloc] initWithRecordType:@"ShoppingLists" predicate:[NSPredicate predicateWithValue:YES]];

    [_privateDB performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {

        for(CKRecord *record in results) {

            ShoppingList *shoppingList = [[ShoppingList alloc] initWithRecord:record];
            [self getItemsByShoppingList:shoppingList result:^(NSArray *results, NSError *error) {

                shoppingList.noOfGroceryItems = results.count;

            }];

        }

        **getAllShoppingLists(results,error);** THIS RETURNS WITHOUT THE noOfGroceryItems BEING UPDATED

    }];
}

我该怎么做才能解决这个问题?有没有更好的方法使用CKQuery简单地获取杂货商品的总数而不是在每个购物清单上为每个商品运行一个?

2 个答案:

答案 0 :(得分:0)

您的方法getAllShoppingLists在不更新您的购物清单的情况下返回,因为performQuery是一种异步方法。它将在一个单独的线程中执行该请求。因此getAllShoppingLists将立即返回。 performQuery块中的代码将在检索到这些对象后被调用。

要测试它,请使用调试器运行它并在每个块中放置断点。这样你就可以看到每个人如何被召唤。

答案 1 :(得分:0)

您可以通过使异步方法同步来解决这个问题。通常这是通过使用信号量来完成的。

有关示例,请参阅:How do I wait for an asynchronously dispatched block to finish?

但是最好让它保持异步并在设置计数时继续你想做的事情。一种解决方案是将代码块传递给getAllShoppingLists方法,并在设置计数后立即执行该块。