NSFetchedResultsController 的 NSFetchedResultsChangeUpdate 事件中的 NSRangeException 异常 [英] NSRangeException exception in NSFetchedResultsChangeUpdate event of NSFetchedResultsController
问题描述
我有一个 UITableView
,它使用 NSFetchedResultsController
作为数据源.
I have a UITableView
that uses an NSFetchedResultsController
as data source.
核心数据存储在多个并行运行的后台线程中更新(每个线程使用自己的NSManagedObjectContext
).
The core data store is updated in multiple background threads running in parallel (each thread using it's own NSManagedObjectContext
).
主线程观察NSManagedObjectContextDidSaveNotification
通知并使用 mergeChangesFromContextDidSaveNotification:
更新它的上下文.
The main thread observes the NSManagedObjectContextDidSaveNotification
notification and updates it's context with mergeChangesFromContextDidSaveNotification:
.
有时NSFetchedResultsController
会发送一个NSFetchedResultsChangeUpdate
事件的 indexPath 不存在到那个时候就没有了.
Sometimes it happens that the NSFetchedResultsController
sends an
NSFetchedResultsChangeUpdate
event with an indexPath that does not exist
anymore at that point.
例如:fetched results controller的结果集包含1 个部分,包含 4 个对象.第一个对象在一个线程中被删除.最后一个对象在不同的线程中更新.然后有时发生以下情况:
For example: The result set of the fetched results controller contains 1 section with 4 objects. The first object is deleted in one thread. The last object is updated in a different thread. Then sometimes the following happens:
- controllerWillChangeContent:被调用.
- controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: 被调用类型 = NSFetchedResultsChangeDelete,indexPath.row = 0.
- controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: 被调用类型 = NSFetchedResultsChangeUpdate,indexPath.row = 3.
但是获取的结果控制器现在只包含 3 个对象,并且如果调用
But the fetched results controller contains only 3 objects now, and if call
MyManagedObject *obj = [controller objectAtIndexPath:indexPath]
根据NSFetchedResultsChangeUpdate
更新table view cell事件,这会因 NSRangeException
异常而崩溃.
to update the table view cell according to the NSFetchedResultsChangeUpdate
event, this crashes with a NSRangeException
exception.
感谢您的任何帮助或想法!
Thank you for any help or ideas!
推荐答案
我现在找到了解决我的问题的方法.在更新事件的情况下,不需要调用
I have now found a solution for my problem. In the case of an update event, there is no need to call
[self.controller objectAtIndexPath:indexPath]
因为更新的对象已经作为 anObject 参数提供给 -controller:didChangedObject:...
委托.
because the updated object is already supplied as the anObject parameter to the -controller:didChangedObject:...
delegate.
因此,我将 -configureCell:atIndexPath:
替换为直接使用更新对象的 -configureCell:withObject:
方法.这似乎没有问题.
I have therefore replaced -configureCell:atIndexPath:
by a -configureCell:withObject:
method that uses the updated object directly. This seems to work without problems.
代码现在看起来像这样:
The code looks now like this:
- (void)configureCell:(UITableViewCell *)cell withObject:(MyManagedObject *)myObj
{
cell.textLabel.text = myObj.name;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCellIdentifier"];
[self configureCell:cell withObject:[self.controller objectAtIndexPath:indexPath]];
return cell;
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
/* ... */
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] withObject:anObject];
break;
/* ... */
}
}
这篇关于NSFetchedResultsController 的 NSFetchedResultsChangeUpdate 事件中的 NSRangeException 异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!