为什么NSArrayController连续两次获取?

时间:2016-04-10 13:10:46

标签: objective-c macos core-data

我在使用Core Data和NSArrayController的OS X应用程序中遇到了一些奇怪的行为。发送到阵列控制器的每个fetch:消息都会导致持久性存储(sqlite)中的 double fetch ,当然需要两倍的时间来进行提取。

当我设置数组控制器的fetchPredicate属性然后发送fetch:message时会发生这种情况。

我使用标准苹果核心数据应用模板创建了一个简单的测试应用,其中一个实体'SomeEntity'只有一个属性'stringAttribute'。我将NSArrayController子类化并覆盖了fetchWithRequest:merge:error:设置断点并查看数组控制器何时从存储中获取。

然后,我写了一个简单的动作方法(连接到按钮),只包含两行:

self.arrayController.fetchPredicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"];
[self.arrayController fetch:self];

而且,每次按下按钮时,fetchWithRequest:merge:error:方法被调用两次,导致两次访问持久性存储。

NSArrayController继承自实现fetch:方法的NSObjectController。文档说

  

从OS X v10.4开始,此方法的结果将推迟到runloop的下一次迭代,以便错误呈现机制可以作为工作表提供反馈。

fetchWithRequest:merge:error:确实由运行循环机制中触发的NSInvocation调用。在一个小断点设置后,我发现一行NSInvocation由行

创建
self.arrayController.fetchPredicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"];

和下一行的第二个

[self.arrayController fetch:self];

当我注释掉第二行时,控制器根本没有取出。因此,只要我想在获取之前设置fetch谓词,我就会得到两次提取。奇怪的是,当我在应用程序启动后第一次按下我的按钮时,就不会发生这种情况。

这感觉很奇怪,因为我基本上只在标准的Core Data堆栈中添加了两行代码。当我用测试数据填充商店并测量时间fetchWithRequest:merge:error:需要完成,我可以清楚地看到两次获取的性能问题并花费两倍的时间。

直接调用fetchWithRequest:merge:error:不是理想的解决方案,因为NSArrayController中有一些自动化功能,我必须重新实现自己。并且它不应该是首先设置fetchPredicate而不是简单地调用fetch的正确方法:?

这里有什么想法?

0 个答案:

没有答案