gpt4 book ai didi

iOS-MagicalRecord/AFNetworking/NSFetchedResultsController-后台重新同步过程导致永久挂起

转载 作者:可可西里 更新时间:2023-11-01 03:59:33 24 4
gpt4 key购买 nike

所以我想要达到的目标

是一个同步过程,应该使用AFNetworking和Magical Record在后台完成,但是当挂接到NSFetchedResultsController的 View Controller 当前处于打开状态或已打开(但弹出)时,会导致永久挂起。

该应用程序在用户第一次打开手机时进行同步,然后通过Magical Record框架始终使用Core Data持久性存储中的数据。然后,当用户希望确保数据为最新版本时,他们进入设置并单击“重新同步”,这将导致执行以下代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
[[CoreDataOperator sharedOperator] commenceSync:self];
});

这将使用单例CoreDataOperator(NSObject的子类-也许应该是NSOperation?)启动同步过程,从而触发以下代码:
[[ApiClient sharedClient] getDataRequest];

然后,这会触发单例AFHTTPClient子类中的这个坏男孩:
[[ApiClient sharedClient] postPath:url parameters:dict
success:^(AFHTTPRequestOperation *operation, id responseObject) {
[request.sender performSelector:request.succeeded withObject:response];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[request.sender performSelector:request.failed withObject:response];
}
];

有效地表示:AFHTTPClient发布此信息,并在成功后将信息传递回提供的选择器(我知道这是通用的,但请求不是问题)

现在,对A​​FNetworking进行编码,以便在主线程上调用所有完成选择器(在本例中为成功和失败)。因此,为了防止阻塞主线程,将处理响应并准备进行保存的代码发送回后台线程:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
id responseData;
[self clearAndSaveGetData:responseData];
});

然后,这将使用Magical Record框架(仍在后台线程中)调用导致保存的函数:
NSManagedObjectContext *localContext = [NSManagedObjectContext contextForCurrentThread];

[DATAENTITY truncateAllInContext:localContext];
<!--- PROCESS DATA INTO DATAENTITY -->
[localContext saveNestedContexts];

我选择 saveNestedContexts是因为自从我在后台工作以来,我希望它一直将其推进到默认上下文(我假设它是父上下文)? (但是到目前为止,这还不是问题)。

现在,这些数据可以变成成千上万的行,因此我正在使用NSFetchedResultsController安全有效地访问此数据,并且它们在与设置或主页不同的 View Controller 中使用。

这是三种情况:
  • 包含FRC的ViewController尚未被访问(不可见且之前不可见)-后台同步工作正常,由于节省了堆栈,因此略有滞后。
  • 包含FRC的ViewController已被访问,并且当前可见-后台同步过程 HANGS ,因为似乎FRC正在接收上下文更新。
  • 以前已访问过包含FRC的ViewController,但当前不可见(使用以下代码弹出了VC:VC),并且在ViewDidUnload中将FRC设置为nil-后台同步过程由于显示的内容而导致手握成为FRC接收上下文更新(就像情况2一样)。

  • [PS:挂了几分钟后,我杀死了调试器,并在以下代码上给了我SIGKILL,这就是为什么我保证FRC正在接收导致挂起的上下文更新:
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
    {
    UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;
    [tableView endUpdates]; <---- SIGKILL
    }

    注意事项的其他重要信息:
  • 我正在使用2个独立的FRC,一个用于普通ALL数据,另一个用于搜索
  • 我在FRC和单独的搜索FRC上都使用了一个缓存,该缓存在适当的时间清除(在此上下文更新之前)
  • FRC正在主线程中进行提取(当存在成千上万的数据行时,它会导致轻微的挂起),我一直在考虑在后台进行提取,但是目前尚未实现。

  • 问题:
  • 为什么在可见或弹出VC的地方会发生这种挂起?
  • 如何使FRC不监听保存,而是使用保存的内容,直到保存完成,然后刷新数据(除非这已经发生并引起挂起)?
  • 将实现后台获取(因为使用FRC打开VC来访问数千行数据时出现滞后会造成明显的滞后,即使使用缓存和减少的谓词/节头(介于1-4秒之间)也可以) ?太复杂了?如何做呢?

  • 谢谢,希望我对我的问题足够详细。

    最佳答案

    我知道这个问题很旧,但是由于这是MagicalRecord的常见陷阱,因此以下内容可能会有所帮助。

    该问题是由FRC的fetchRequest和保存操作彼此死锁引起的。以下为我解决了它:

    更新到最新的MagicalRecord版本(在撰写本文时为2.1)。

    然后使用以下方法进行所有背景保存:

    MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    // create new objects, update existing objects. make sure you're only
    // accessing objects inside localContext
    [myObjectFromOutsideTheBlock MR_inContext:localContext]; //is your friend
    }
    completion:^(BOOL success, NSError *error) {
    // this gets called in the main queue. safe to update UI.
    }];

    关于iOS-MagicalRecord/AFNetworking/NSFetchedResultsController-后台重新同步过程导致永久挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11655771/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com