为什么 NSFetchedResultsController performFetch: 在使用等效的 NSFetchRequest 重新创建 NSFetchedResultsController 时崩溃?

jas*_*ori 5 iphone crash core-data

为什么[NSFetchedResultsController performFetch:]在重新创建NSFetchedResultsController具有等效项时会崩溃NSFetchRequest

我有一个应用程序,它有一个线程(消息线程)的表视图控制器。当您点击一个线程时,它会加载另一个表视图控制器,该控制器使用 NSFetchedResultsController 来获取该线程的所有消息并显示它们。我使用 NSFetchedResultsController 因为我可以在后台加载消息/删除/添加新消息,而根本不用担心显示它们。

第二个表视图控制器用于所有线程,所以当我点击返回然后点击另一个线程时,我只是删除当前的 NSFetchedResultsController 并为新线程设置一个新的。

以下是重现 CRASH 的步骤:

  1. 点按一个线程,以便它向我显示消息。
  2. 重新加载消息,以便 NSFetchedResultsController 用于显示新消息。
  3. 回去。
  4. 点击另一个线程。
  5. 回去。
  6. 点击第一个线程。

在点击 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
Run Code Online (Sandbox Code Playgroud)

3是我的方法

有什么想法吗?任何帮助将非常感激。


解决了!

这是我的错。我使用的是从另一个键值派生的 sectionNameKeyPath。只要 NSFetchRequest 按该键值排序就可以了。问题是它是动态生成的,因为我不想浪费数据库中的空间。我在 NSManagedObject 类中使用了一个由 didTurnIntoFault 清理的实例变量。

现在,我认为实例变量必须已创建然后丢弃,然后在某个时候重新创建,从而使 NSFetchedResultsController 的排序陷入停顿。

这解释了为什么没有 sectionNameKeyPath 或委托解决了这个问题。

现在,我已经切换到 CoreData 对象中保存的键值,它似乎工作得很好。

jas*_*ori 0

是我的错。我使用的是从另一个键值派生的sectionNameKeyPath。只要 NSFetchRequest 按该键值排序就可以。问题是它是动态生成的,因为我不想为其浪费数据库空间。我在 NSManagedObject 类中使用了一个实例变量,该变量已被 didTurnIntoFault 清理。

现在,我认为实例变量必须先被创建,然后被丢弃,然后在某个时刻重新创建,从而使 NSFetchedResultsController 的排序陷入停顿。

这解释了为什么没有使用sectionNameKeyPath或委托来解决问题。

现在,我已切换到 CoreData 对象中保存的键值,它似乎工作得很好。