在后台/前台模式下运行冗长的核心数据删除

Posted

技术标签:

【中文标题】在后台/前台模式下运行冗长的核心数据删除【英文标题】:Lengthy core-data delete run in background/foreground mode 【发布时间】:2014-07-16 09:54:18 【问题描述】:

我有一个非常冗长的核心数据删除任务,其中包含 92k 条奇怪的记录,这需要很长时间才能运行。最初它锁定了 UI 线程,所以我试图将调用放在后台线程上。然而,我在模拟器中注意到的是,当我在应用程序后台运行时,此任务停止运行。

我想知道是否有一个快速调整我可以制作代码,以便一旦应用程序在后台运行 10 分钟或允许它们运行多长时间,我的删除将继续运行。

当我开始上课时,我会创建一个后台队列:

backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, nil);

然后什么时候删除我的对象

- (void)queueForDelete:(FlightRecording *)flight 

    NSError *error = nil;
    flight.deleteFlagValue = 1;
    [managedObjectContext save:&error];

    // Remove flights form Internal table dataStructure
    [flightList removeObjectAtIndex:[tmpIndexPath row]];
    [[self tableView] deleteRowsAtIndexPaths:@[tmpIndexPath] withRowAnimation:UITableViewRowAnimationFade];

    //Queue flight for deletion in the background
    dispatch_async(backgroundQueue, ^
        NSLog(@"Adding %@ to deletion Queue", flight.getFileName);
        [self deleteFlight:flight];
    );
    [[self tableView] reloadData];

此代码确实使 UI 响应更快,但删除我的对象仍需要大约 5 到 10 分钟(在模拟器中)。我希望用户能够在后台运行应用程序并让删除过程仍在运行,因为无论后台/前台如何,它都会对应用程序的响应能力产生影响。

【问题讨论】:

只是一个观察 - 因为你打电话给deleteRowsAtIndexPaths,所以没有必要打电话给reloadData 【参考方案1】:

NSManagedObjectContext -performBlock: 调用中执行此任务。在具有私有队列并发类型的子上下文上执行此操作。这将为您提供异步处理。

不要在每次调用时保存上下文。

不要在每次调用时更新您的表格视图(reloadDatadelteRowsAtIndexPaths)。这是一个模型任务。不要更新 UI。

您对tmpIndexPath 的使用是代码异味。这是将模型任务与视图任务混合的另一个迹象。删除一堆对象纯粹是一个模型任务。编写代码,假设不存在 UI 或控制器。

【讨论】:

会开始删除每条记录的单个子上下文吗?还是我一直在使用 preformBlocks 的子单子上下文? 两者都不是。但你很接近。创建一个子上下文。向它发送一个 -performBlock 将遍历所有要删除的对象,然后删除它们。在该块的末尾,保存您的子上下文。检查结果(它可能会成功,除非出现外部错误)。在块内,就在它结束之前,将主线程上的调用(异步)排入队列,以告诉主线程可以更新 UI。 关于 tmpIndexPath => 我所做的是将模型与核心数据分开,因此我手动将数据模型生成到数组中,而不是处理 fetchedResultsController。 tmpIndexPath 是更新对象中的“准备删除”标志,因此当我重新生成模型时,它们会被排除在外

以上是关于在后台/前台模式下运行冗长的核心数据删除的主要内容,如果未能解决你的问题,请参考以下文章

访问前台 MySql 后台运行时错误 7878

浏览器可以检测浏览器何时在前台或后台模式下运行? [复制]

帝国cms后台改东西前台无反应

React-native-agora 音频仅在后台模式下无法在前台模式下工作(iOS)

如何从后台service传递数据到前台正在运行的activity

总结-前台发送前台页面增删改查数据发送并调用后台控制器方法