【发布时间】:2009-10-05 21:49:28
【问题描述】:
为什么[NSFetchedResultsController performFetch:] 在使用等效的NSFetchRequest 重新创建NSFetchedResultsController 时会崩溃?
我有一个具有线程表视图控制器(消息线程)的应用程序。当您点击一个线程时,它会加载另一个表视图控制器,该控制器使用 NSFetchedResultsController 来获取该线程的所有消息并显示它们。我使用 NSFetchedResultsController 因为我可以在后台加载消息/删除/添加新消息,而根本不用担心显示它们。
第二个表格视图控制器用于所有线程,所以当我点击返回然后点击另一个线程时,我只是删除当前的 NSFetchedResultsController 并为新线程设置一个新的。
以下是重现 CRASH 的步骤:
- 点按一个话题,它就会向我显示消息。
- 重新加载消息,以便 NSFetchedResultsController 用于显示新消息。
- 返回。
- 点击另一个线程。
- 返回。
- 点击第一个线程。
在点击 NSFetchedResultsController 时,会创建与第一个相同的 NSFetchedResultsController。 (相同的缓存和一切)。如果它给出这个错误和崩溃,而不是像它那样工作:
Program received signal: “EXC_BAD_ACCESS”.
NSFetchedResultsController 正在向已释放的对象发送消息。
这是堆栈跟踪:
#0 0x95ffd688 in objc_msgSend
#1 0x0060699b in -[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:]
#2 0x00601bf0 in -[NSFetchedResultsController performFetch:]
#3 0x0001c170 in -[CMNewMessagesViewController loadMessagesViewControllerForThread:showProfile:] at CMNewMessagesViewController.m:331
3 是我的方法
有什么想法吗?任何帮助将不胜感激。
已解决!
这是我的错。我使用的是从另一个键值派生的 sectionNameKeyPath。只要 NSFetchRequest 按该键值排序就可以了。问题是它是动态生成的,因为我不想为此浪费数据库中的空间。我在 NSManagedObject 类中使用了一个实例变量,它由 didTurnIntoFault 清理。
现在,我认为必须创建实例变量然后丢弃,然后在某个时候重新创建,从而使 NSFetchedResultsController 的排序停止。
这解释了为什么没有 sectionNameKeyPath 或委托来解决问题。
现在,我已经切换到 CoreData 对象中保存的键值,它似乎工作得很好。
【问题讨论】: