Ios NSManagedObject的设置属性正在阻止iPad UI';核心数据中

Ios NSManagedObject的设置属性正在阻止iPad UI';核心数据中,ios,core-data,nsfetchedresultscontroller,nsmanagedobject,Ios,Core Data,Nsfetchedresultscontroller,Nsmanagedobject,首先,我发现了一些关于这个问题的相关问题,并在下面粘贴了链接,但没有一个真正帮助我解决这个问题: 我有一个包含大约5000行的tableview,它当前由一个“获取结果”控制器管理 每行显示文档实体的基本属性,还包括一个按钮,供用户将特定文档标记为收藏夹。诚然,文档实体与几个不同的实体有关系,底层SQLite数据库是largeish(~20mb) 获取每一行的属性相对较快,并且表视图在处理这么多项时表现相当好。保存更改也不是问题 当我试图更改文档实体的isFavorite(BOOL)属性时,

首先,我发现了一些关于这个问题的相关问题,并在下面粘贴了链接,但没有一个真正帮助我解决这个问题:

我有一个包含大约5000行的tableview,它当前由一个“获取结果”控制器管理

每行显示文档实体的基本属性,还包括一个按钮,供用户将特定文档标记为收藏夹。诚然,文档实体与几个不同的实体有关系,底层SQLite数据库是largeish(~20mb)

获取每一行的属性相对较快,并且表视图在处理这么多项时表现相当好。保存更改也不是问题

当我试图更改文档实体的isFavorite(BOOL)属性时,问题就出现了。此属性在按钮触碰内部事件时设置/更新,包括:

[document setIsFavourite:[NSNumber numberWithBool:![document isFavourite]]]
这里的问题是,每次点击收藏夹按钮时,这一行代码都会将UI阻塞约1-2秒,这显然是不理想的

我尝试过将isFavorite属性标记为索引,以及增加获取批处理大小,最后为NSFetchedResultsController创建缓存,但似乎对性能没有任何帮助

我设法避免UI锁定的唯一方法是在后台线程上执行属性设置,但这涉及到创建新上下文、注册通知以及在保存上下文时合并更改。在这种情况下,会出现另一个问题,因为当我用合并更改响应保存通知时,我的“获取结果”控制器似乎变得混乱,更改的行会自动从我的tableview中删除,而恢复该行的唯一方法是执行[tableview重新加载数据]

是否有其他人遇到过类似的问题,我是否可以尝试解决其他问题

多谢各位


Rog

该行不应导致挂起,因为不必提取任何内容。您的内存中已经有文档对象,并且您只更改了该对象在内存中的一个属性

我能想到的只有两个原因,为什么这样一条线会导致挂起

首先,您有一个用于
setisfavorite:
的自定义访问器,该访问器会触发一些副作用,这些副作用会导致错误和回迁。例如,当
isfavorite
属性更改触发获取的属性时,会触发自定义逻辑

我倾向于这种解释,因为您使用的是旧的参考表格,而不是:

document.isFavourite=[NSNumber numberWithBool:![document isFavourite]];
如果手动创建了
文档
对象的类,请检查属性是否使用了
@dynamic
而不是
@synthesis
。后者不能很好地处理NSManagedObject子类

其次,在触发类似级联的属性上设置了验证,例如,验证必须检查另一个对象中的属性


我很怀疑这行代码实际上是问题的根源

你是怎么确认那条线导致了悬挂的?仪器是你的朋友。如果这条线真的是违规者,我会使用仪器来查看是什么kvo observer导致您暂停。@ImHuntingWabbits我尝试过仪器,但出于某种原因,它不允许我在iOS上运行任何核心数据模板(它说它不兼容)。还有其他方法吗?您不需要运行任何CoreData模板,只要在UI响应点击后使用时间分析器查看是什么导致了您的速度减慢。进一步调查后,我认为您可能是对的,这一行不是我问题的真正原因,而是触发它的原因。我相信此属性值更改会触发获取结果控制器/表视图更新方法,在本例中,这些方法完全不必要,因此我想知道是否有可能以某种方式防止这种情况发生(对于特定属性)?我用一个简单的fetch请求做了一个测试,它工作得很好(我根据需要手动更新UI)。在
controller:didChangeObject:atIndexPath:forChangeType:newindepath:
中检查您的代码,看看在进行更改时会发生什么。您有任何自定义访问器吗?是的,正如预期的那样,当属性更改时会触发该开关,但有趣的是,它所做的只是调用
configureCell:atIndexPath:
,这实际上会更新UI,以显示该项已标记为收藏夹。我不明白为什么这会是一项如此昂贵的任务,以至于需要锁定一点UI?它不应该。这是一项非常普通的任务。答案在代码详细信息中。您可以使用工具来分析代码,或者如果您不熟悉工具,只需在可疑方法的开始和结束处记录一个时间戳。这将确切地告诉您哪种方法陷入困境。再次感谢你的帮助,我会看看我是怎么做的,并在途中发布我的发现。