RestKit,核心数据,神奇的记录,大量数据和滞后的 UI

Posted

技术标签:

【中文标题】RestKit,核心数据,神奇的记录,大量数据和滞后的 UI【英文标题】:RestKit, Core Data, Magical Record, Lots of data and Lagging UI 【发布时间】:2015-04-07 00:40:29 【问题描述】:

我有一个应用程序可以存储有关餐馆的数据。他们的菜单,时间表等等。 到目前为止,DB 中约有 200 家餐厅。该应用程序曾经一次检索这些地方,但是加载时间太长,因此我决定将数据逐个加载。在启动应用程序向服务器询问一组地点的 id,然后通过 API 获取数据。

我将 RK 操作的完成块设置为后台队列,但这没有帮助。滚动运行不够流畅,有时应用程序甚至死锁(原文如此!)或崩溃,控制台中没有错误输出。我尝试使用 Instruments 来定位导致 UI 变得生涩的原因,但没有成功。我什至关闭了图像加载和排序功能。我曾经将 RK 的请求调用包裹在 @synchronized 中,所以我删除了它,但没有效果。

在使用了几周的 Objective-c 经验后,我从没想过我会遇到这种问题。我已经尝试了所有可能出现在我脑海中的方法,所以现在我有点放弃了。

请帮帮我:)

以下代码在应用启动后立即被调用 200 次。

NSURLRequest *request = [[DEAPIService sharedInstance].manager requestWithObject:nil
                                                                              method:RKRequestMethodGET
                                                                                path:path
                                                                          parameters:params];
    //DLog(request.URL.absoluteString);

    NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_contextForCurrentThread]];

    RKManagedObjectRequestOperation *operation = [[DEAPIService sharedInstance].manager managedObjectRequestOperationWithRequest:request
                                                                                                        managedObjectContext:context
                                                                                                                         success:success
                                                                                                                         failure:failure];

    // dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.name.bgqueue", NULL);
    operation.successCallbackQueue = backgroundQueue;

    [[DEAPIService sharedInstance].manager enqueueObjectRequestOperation:operation];

在此之前设置响应描述符。数据库中也有很多关系。我查看了数据库的文件大小——大约 1.5Mb。我想知道如果有超过 1k 家餐厅会发生什么。这是加载此类数据的好方法吗?最好的做法是什么?

【问题讨论】:

您是如何以这种方式使用 RK 和 MR 的? 您使用 MR 是否有原因,以及您自己创建请求操作队列的原因? 我不是该应用程序的作者,所以我不知道为什么以前的人会这样做。我检查了 MR 的代码,它只是初始化了一个并发类型为 NSPrivateQueueConcurrencyType 的子上下文。 MR 在整个应用程序中都使用,我想为了方便起见,例如,您可以通过一行代码获取 DB 中的第一个对象: APPlace *place = [APPlace MR_findFirst]; 你的 RK 使用情况如何?您是否使用对象管理器来控制整个过程,并且 RK 是否完全绑定到 Core Data 堆栈中(或者这就是执行上下文洗牌的原因)? @Wain 我对 RK 不太熟悉,所以我不知道它是否“完全绑定”。 DEAPIService 的属性“经理”是 RKObjectManager。我想它被这段代码捆绑了:gist.github.com/anonymous/274b038db7482f21b320 【参考方案1】:

好的,根据提供的信息,您应该可以简化很多。目前,您的代码正在下降到一个低级别,并涉及您希望留给 RestKit 整理的线程和上下文管理。从外观上看,您有一个正确配置的对象管理器和核心数据堆栈,因此您应该让它完成工作。

这意味着删除请求、上下文和请求操作代码并简单地调用`getObjectsAtPath:parameters:success:failure:'。 RestKit 将在后台处理所有下载和映射并保存上下文。

您还应该在整个应用程序中真正使用获取结果控制器,如果您这样做了,它们会自动检测 RestKit 保存的更改并更新您的 UI。

一旦你做到了,任何对 UI 的阻塞都与 RestKit 和你的下载要求无关,应该与后续的图像管理/下载有关。

【讨论】:

它有部分帮助,但滚动仍然有点生涩。问题还可能出在哪里?可以涉及关系吗?一个 Place 对象有 4 个。这是一个响应描述符设置:gist.github.com/anonymous/846599751c215a49acf5 我确实有一个获取的结果控制器,即使如此我还没有知道它是如何实际获取到核心数据的。我曾经更改过内容的 UI 更新,但它每秒被调用多次,所以我删除了引用。 RK 在后台进行所有数据处理,所以除非你已经淹没了 CPU,否则它不会导致 UI 延迟。您可能应该提出一个新问题,该问题显示当 FRC 进行更改时您必须更新 UI 的代码。分析也应该可以帮助您现在找到问题。

以上是关于RestKit,核心数据,神奇的记录,大量数据和滞后的 UI的主要内容,如果未能解决你的问题,请参考以下文章

核心数据和神奇的记录

用新的位置数据更新核心数据(神奇的记录)

如何将查询更改为核心数据(神奇记录)中的获取结果?

自定义验证期间神奇记录核心数据中的上下文保存问题

RestKit 核心数据集成

Restkit核心数据明细数据