核心数据:性能问题。 Instruments 的输出是神秘的
Posted
技术标签:
【中文标题】核心数据:性能问题。 Instruments 的输出是神秘的【英文标题】:Core Data: performance issue. Instruments's output is cryptic 【发布时间】:2014-04-24 15:37:26 【问题描述】:我以基本方式使用 Core Data 和 RestKit(只是默认的 RestKit 设置)。
UI 有时会卡住很长时间(在 iPhone 5 上是 50 秒)。可以有很多对象,但没有什么疯狂的,而且对象很小(没有图像等)。
我怀疑这是由于一些上下文保存,但我不确定:我从来没有在我的应用程序中手动保存内容。
Instruments 的 Time Profiler 清楚地显示了卡住的原因,但我不明白输出或导致这种情况的原因。最重的堆栈跟踪如下所示:
14 57129.0 Main Thread 0x4ea79 :0
13 CoreData 56680.0 -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:]
12 CoreData 56523.0 -[NSManagedObjectContext executeFetchRequest:error:]
11 CoreData 56462.0 -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]
10 CoreData 56442.0 -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:]
9 CoreData 56291.0 -[NSManagedObjectContext executeFetchRequest:error:]
8 CoreData 50210.0 -[NSPersistentStoreCoordinator executeRequest:withContext:error:]
7 CoreData 50193.0 -[NSMappedObjectStore executeFetchRequest:withContext:]
6 CoreData 49978.0 -[NSDictionaryStoreMap handleFetchRequest:]
5 Foundation 36516.0 -[NSPredicate evaluateWithObject:]
4 Foundation 35865.0 -[NSComparisonPredicate evaluateWithObject:substitutionVariables:]
3 Foundation 16845.0 -[NSFunctionExpression expressionValueWithObject:context:]
2 CoreData 11823.0 -[NSDictionaryMapNode valueForKey:]
1 CoreFoundation 1225.0 -[__NSCFString isEqualToString:]
0 libobjc.A.dylib 36.0 -[NSObject class]
有人能指出正确的方向吗?
【问题讨论】:
看起来您正在主线程上执行一个长提取请求(在 CoreData 上保存 50 秒将是一个巨大的保存)。长操作(网络、数据库等)应该在后台线程上执行,然后更新到主线程上执行的 UI。 谢谢@RoboticCat。问题是我什至不知道是什么触发了这个获取(也不知道它实际上是什么)。它是通过私有 API _parentObjectsForFetchRequest 完成的。 某处(在您的代码中或在您包含的框架之一中)有大量的 CoreData 活动。这种情况发生在哪里,只有你自己知道;必须有一系列步骤导致此活动。我很惊讶您从未手动保存 CoreData(这是 UIManagedDocument 吗?),但无论如何您都必须弄清楚发生这种情况的位置。试一试Call Tree
(如Hide System Libraries
)中的复选框,这样您就可以尝试追踪调用CoreData 命令的内容。
另外,还有一个Core Data
分析选项;我不确定它是否会有所帮助,但其中可能有一些东西。
分析显示什么? RestKit 通常不会在主线程上运行任何 fetch...
【参考方案1】:
您是否尝试在核心数据设置期间将托管对象缓存设置为RKInMemoryManagedObjectCache
?在 github 上看到此问题后,我尝试了此操作:https://github.com/RestKit/RestKit/issues/1232,它显着加快了我的 restkit/core 数据基准测试。下面是代码的样子:
objectManager.managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext: managedObjectStore.persistentStoreManagedObjectContext];
来自http://restkit.org/api/0.20.0/Classes/RKInMemoryManagedObjectCache.html 的 RestKit 文档:“(RKInMemoryManagedObjectCache) 提供快速的托管对象缓存,其中对象实例保留在内存中以避免命中核心数据持久存储。与基于获取请求的策略相比,性能大大提高内存消耗的代价。”
【讨论】:
以上是关于核心数据:性能问题。 Instruments 的输出是神秘的的主要内容,如果未能解决你的问题,请参考以下文章