NSFetchedResultsController 让我发疯
自 1 个月以来,我一直在使用 NSFetchedResultsController 构建应用程序,并在 3.1.2 SDK 上测试该应用程序。问题是我一直在我的应用程序中到处使用 NSFetchedResultsController 并正在开发 3.1.2 版本的 SDK,现在我的客户说我应该使其与 3.0 版本兼容,并且截止日期快到了。
但是每次我更改控制器处理的对象时都会崩溃,应用程序会因非常奇怪的错误而崩溃。
当删除一个部分中的最后一个对象以及当更改使对象喜欢另一个部分时,就会出现问题。
我一直在使用来自 Dave Mark 和 Jeff LaMarche 的“More iPhone 3 Development Tackling iPhone SDK 3”中的示例代码。我还添加了 链接文本的一些更改
这是应用程序崩溃时控制台的示例输出。
*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“更新无效:部分数量无效。”更新后表视图中包含的节数 (1) 必须等于更新前表视图中包含的节数 (2),加上或减去插入或删除的节数(2 个插入,0 个已删除)。 2010-03-14 16:23:29.758 Instaproofs[5879:207] 堆栈:( 807902715, 7364425, 807986683, 811271572, 815059090, 815007323, 211023, 4363331, 810589786, 807635429, 810579728, 3620573, 3620227, 3614682, 3609719, 27337, 810595174, 807686849, 807683624, 839142449, 839142646, 814752238 )
如果我知道 NSFetchedResultsController 有这么多 bug,我就永远不会使用它。
所以基本上我需要 NSFetchedResultsControllerDelegate 才能在 3.0 及更高版本的 SDK 上正常工作。
如果有人帮助我找出我做错了什么,这将是我的救星。
i've been building an app since 1 month using NSFetchedResultsController and i was testing the app on the 3.1.2 SDK. The poblem is that i've been using NSFetchedResultsController everywhere in my app and was working on the 3.1.2 version of the SDK, now my client say that i should make it compatible with the 3.0 version and the deadline is almost there.
But is crashing everytime i change an object handled by the contoller, the application is crashing with very weird errors.
The problem occure when removing the last object in a section and when a change make an object love to another section.
I've been using a sample code from "More iPhone 3 Development Tackling iPhone SDK 3" by Dave Mark and Jeff LaMarche. I've also included some changes from link text
Here is a sample output of the console when the application is crashing.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (2 inserted, 0 deleted).'
2010-03-14 16:23:29.758 Instaproofs[5879:207] Stack: (
807902715,
7364425,
807986683,
811271572,
815059090,
815007323,
211023,
4363331,
810589786,
807635429,
810579728,
3620573,
3620227,
3614682,
3609719,
27337,
810595174,
807686849,
807683624,
839142449,
839142646,
814752238
)
If i knew that NSFetchedResultsController is so buggy, i would never used it.
So basicaly i need the my NSFetchedResultsControllerDelegate to work fine on the 3.0 and above SDKs.
It would be life saver if someone help me figure out what i'm doing wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从错误消息中可以看出,您在应该删除部分时却将其插入表中。即使您已告诉 tableView 总共需要四个部分,您的 tableView 数据源在更新后仅提供一个部分。
我不认为这是 NSFetchedResultsController 有问题的情况,而是在简单用例之外实现起来很棘手。您的崩溃几乎肯定是由于您的controller:didChangeObject:atIndexPath:forChangeType:newIndexPath 委托方法而发生的。成功实现此方法的关键(至少根据我的经验)是要记住changeTypes 是对象和indexPath 驱动的。这使得“更新”和“移动”在概念上变得棘手。
考虑托管对象发生更改以使其在新的sectionNameKeyPath 下排序的情况。从概念上讲,我们认为该对象已“移动”到新部分,因为 fetchedResultsController 现在将其排序在 tableView 中的新标题下。但是,如果对象的 indexPath 没有更改,则 fetchedResultsController 会认为这是“更新”而不是“移动”。
更糟糕的是,即使更改的托管对象仍然保留相同的索引路径,fetchedResultsController 中的其他对象现在可能具有新的索引路径,因为它们因更改而受到影响。这意味着您必须在委托方法的“更新”部分中手动处理部分插入和部分删除。类似的问题需要在委托方法的“移动”部分中解决。
LaMarche 的修复方法是尝试以一种通用的方式来解决这个问题,以容纳尽可能多的用例,而不是试图用太多的话来解释它。通过尝试理解与您的用例相关的问题,您也许能够显着降低 LaMarche 使用的代码的复杂性。特别关注委托方法的“更新”和“移动”部分,因为这些是您的问题最有可能的罪魁祸首。
It appears from your error messages that you are inserting sections into the table when you should be deleting them. Your tableView dataSource is only supplying one section after the updates even though you have told the tableView to expect a total of four sections.
I don't think this is a case of NSFetchedResultsController being buggy, but rather that it is tricky to implement outside of simple use cases. Your crashes are almost certainly occurring as a result of your controller:didChangeObject:atIndexPath:forChangeType:newIndexPath delegate method. The key to successfully implementing this method (at least in my experience) is to keep in mind that the changeTypes are both object and indexPath driven. This makes "updates" and "moves" tricky conceptually.
Consider the situation where a managed object is changed such that it sorts under a new sectionNameKeyPath. Conceptually, we think of the object as having "moved" to a new section since the fetchedResultsController now sorts it under a new heading in the tableView. If the object's indexPath does not change, however, the fetchedResultsController considers this an "update" and not a "move".
What's worse is that even though the managed object that changed still retains the same indexPath, other objects in the fetchedResultsController may now have new indexPaths because they were bumped around by the change. This means that you will have to manually handle section insertions and section deletions in the "update" section of your delegate method. Similar problems will need to be addressed in the "move" section of your delegate method.
Without trying to explain it in so many words, LaMarche's fix is attempting to address this problem in a generic way that accommodates as many use cases as possible. By trying to understand the problem as it pertains to your use case, you may be able to significantly reduce the complexity of the code that LaMarche uses. Focus specifically on the "update" and "move" sections of your delegate method, as these are the most likely culprits for your problem.
查看此资源:
http:// /iphonedevelopment.blogspot.com/2009/11/i-know-youre-tired-of-hearing-about.html
对我帮助很大。
Check out this resource:
http://iphonedevelopment.blogspot.com/2009/11/i-know-youre-tired-of-hearing-about.html
Helped me tremendously.