【问题标题】:Waiting on API response before deleting from SQLite DB在从 SQLite DB 中删除之前等待 API 响应
【发布时间】:2017-09-16 05:07:55
【问题描述】:

我无法想出一种在 JSON 响应后从 SQLite DB 中删除信息的有效方法。

基本上我要做的是:

我有一个包含 100 条记录的数据库。

  1. 我看了第一条记录
  2. 构建 JSON 包并将其发送到我的 API。
  3. 等待 API 响应 Ok 或 Fail
  4. 从数据库中删除记录就OK了。
  5. 移至下一条记录。

在我可以删除并继续之前等待响应之间有一段时间。

一个简单的 FOR 似乎不起作用,因为它无法等待 API 的“OK”。

我查看了dispatch_async(dispatch_get_main_queue());,但如果 OK 出现并且数据库正在处理,它将在数据库被访问时锁定数据库,并且由于数据库被锁定而逻辑失败。

我需要两者的混合。有谁知道教程或从哪里开始这样的事情?

【问题讨论】:

  • 你是不是要遍历这100条记录,询问远程服务“我可以删除这条吗?” - 每次都在等待回复?
  • 是的,没错。
  • 使用blocks接收异步响应,收到响应后在block中执行sqlite操作。
  • 我用dispatch_async queue 尝试过,它只会创建多个实例并锁定数据库。

标签: ios objective-c json sqlite


【解决方案1】:

使用操作队列和您自己的自定义操作。将操作队列设置为串行或设置为允许少量并发操作。

遍历每条记录,为每条记录创建一个操作。将每个操作放入队列中。

该操作的实现将是进行 API 调用,然后如果该 API 调用指示应该删除一条记录,则删除该记录。确保操作的main 在 API 调用完成之前不会结束。

【讨论】:

  • 使用nsoperationqueue 可以帮助我完成此任务吗?
  • 我还没有使用 Swift。仍然是 Objective-C。
  • 是的,NSOperatationQueueNSOperation
  • 有没有机会,一旦我写了它,我可以把它从你那里弹回来,看看我写得是否正确?
  • 您可以发布一个带有相关代码的新问题,清楚地解释您可能遇到的任何问题(如果有)。
【解决方案2】:

创建一个数组,您将在其中临时保存要删除的数据

NSMutableArray* itemsToDelete = [[NSMutableArray alloc] init] 

一旦您收到成功的响应,您就将要删除的项目附加到此数组中。在成功的所有呼叫中执行相同的过程。一旦您在最后一次成功或失败的响应中上传数据完成,请检查 for 循环内的 itemsToDelete 数组并从数据库中删除所有内容

【讨论】:

  • 问题标记为 Objective-C。
  • @rmaddy 感谢将代码行从 swift 更改为 objective-c
【解决方案3】:

我建议使用块来接收来自异步调用的响应。在这种情况下,您可以在块内执行 DB 操作。

dispatch_async(dispatch_get_main_queue()); 不适用于异步调用。它主要用于更新 UI。

所有异步调用都需要在后台线程上完成。

遇到你的问题,你可以这样做:

-(void)checkToDeleteWithCompletion:(MyCompletion)completion{

    __block NSMutableArray *responseArray =  [NSMutableArray array];

  // Create a dispatch group
    dispatch_group_t group = dispatch_group_create();

    for (int i = 0; i < yourArray.count; i++) {
        // Enter the group for each request we create
        dispatch_group_enter(group);

            [self ..methodToPErformAsynccallWithCOmpleton success:^(BOOL success, id response) {
                dispatch_group_leave(group);
                 [responseArray addObject:response];

            } failure:^(NSError *error, NSInteger statusCode) {
                dispatch_group_leave(group);
            }];
     }

    // Here we wait for all the requests to finish
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // Do whatever you need to do when all requests are finished
        completion(YES,[responseArray copy]);
    });
}

最后你可以在 responseArray 上使用 for 循环来删除不需要的对象。

您还可以使用以下方法限制并发调用数:

dispatch_semaphore_create(maxConcurrencyValue)

或者您可以按照 rmaddy 的建议使用 NSOperation!

【讨论】:

  • 这种方法有一个严重的缺陷——你最终会向 API 发出 yourArray.count 并发请求。这通常是个坏主意。
  • 据我所知,我们无法为 N 个异步 api 调用创建 N 个完成块。 @rmaddy。如果您知道更好的处理方法,请指导我!谢谢!在尝试了一些可怕的方法后,我最终得到了这个哈哈!
  • 查看我的答案以获得更好的方法(至少更好地确保仅有限数量的并发 API 调用)。
猜你喜欢
  • 2020-03-05
  • 1970-01-01
  • 2020-03-20
  • 2021-08-02
  • 2021-04-17
  • 2021-11-18
  • 2018-11-09
  • 2011-04-21
  • 1970-01-01
相关资源
最近更新 更多