将 NSDate 设置为 NSManagedObject 很慢?

Posted

技术标签:

【中文标题】将 NSDate 设置为 NSManagedObject 很慢?【英文标题】:Setting NSDate to an NSManagedObject slow? 【发布时间】:2014-06-22 03:08:35 【问题描述】:

我目前正在开发一个核心数据应用程序。我有一个表格视图,它显示属性scheduled(日期)为nilBOOL 属性为NO 的项目列表。每个表格视图单元格中都有一个按钮,允许用户在模式视图中设置日期。模态视图中有一个日期选择器。该项目被传递给该模式视图控制器。

当用户在模态视图中点击完成按钮时设置日期。日期是用这行代码设置的:

self.item.scheduled = self.datePicker.date;

显然,这行代码会导致 UI 被阻止约 1 秒(在第 5 代 iPod touch 上),这是不受欢迎的行为。我用 Instruments 发现-[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] 占用了 900.0ms 以上。

有人可以告诉我是什么导致缓慢吗?我目前只使用一个 MOC。我应该使用另一个来进行更改吗?

编辑: 我从 Instruments 获得的耗时最长的方法告诉我,表格视图控制器似乎试图重新获取或更新单元格,导致运行缓慢。虽然我在发布时传递了-com.apple.CoreData.SQLDebug 1,但在设置日期时没有显示任何消息。

这是我从 Instruments 获得的调用树。

CoreDataTableViewController 摘自我读过的一本关于 Core Data 的书。它与找到的here 基本相同。

【问题讨论】:

试试NSDate* myDate = self.datePicker.date; self.item.scheduled = myDate;,看看哪条线慢? @Pang 试过了,UI还是卡住了。我从 Instruments 获得的耗时最长的方法告诉我,表格视图控制器似乎试图重新获取或更新单元格,导致运行缓慢。我有-com.apple.CoreData.SQLDebug 1 在发布时通过了,但是在设置日期时没有显示任何消息。什么给了? 1.您应该使用最新发现更新您的问题。 2. 设置属性在您提交之前不会运行任何 SQL。 3. 检查self.item.scheduled = self.datePicker.date;是否被意外运行多次。 4. 提供更多信息以供人们帮助,例如仪器中的调用堆栈导致缓慢。 1. CoreDataTableViewController 似乎不是 Apple API 的一部分,所以请说明它来自哪里(here 或 here 或什么)? 2. 说明您的测试环境(ios 版本、硬件或模拟器型号)并尝试在不同的环境中进行测试,3. 不确定 -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] 中的内容,但尝试简化您的 UITableViewCell 的布局。 4.尝试通过将-controller:didChangeObject:atIndexPath:forChangeType:newIndexPath 中的UITableViewRowAnimationFade 更改为UITableViewRowAnimationNone 来禁用动画。希望我或其他人可以帮助你。 【参考方案1】:

我终于found the answer。事实证明,离屏时自动布局非常慢。这就是为什么在调用树中可以看到布局操作花费了大部分时间的原因。

我选择的解决方案是删除表视图控制器作为NSFetchedResultsControllerviewWillDisappear: 中的委托。然后,在viewWillAppear: 中,我执行重新获取并在表视图上调用reloadData,并将NSFetchedResultsControllerdelegate 属性设置回self(这是表视图控制器)。

编辑:正如 cmets 中提到的 amb,上面的解决方案是一个不好的方法。这是better approach。我应该补充一点,我的表格视图只有在我添加时才正确重新加载

if(self.tableView.window == nil)
    return;

也发给controllerWillChangeContent:

【讨论】:

这是一个糟糕的方法。相反,试试这个:aplus.rs/2014/… 非常感谢您提供更好的方法。我已经编辑了答案

以上是关于将 NSDate 设置为 NSManagedObject 很慢?的主要内容,如果未能解决你的问题,请参考以下文章

快速设置 NSDate 0 秒

将持续数天的 NSDate 拆分为几个跨度

将 NSPredicate 设置为 NSFetchRequest 后 executeFetchRequest 崩溃

当用户的设备在 iOS 中设置为 24 小时制时,如何将包含“am/pm”的字符串转换为 NSDate?

在 iOS 中将用户出生日期格式化为 NSDate 对象

将NSDate转换为NSString