NSFetchedResultsController的NSFetchedResultsChangeUpdate事件中的NSRangeException异常 [英] NSRangeException exception in NSFetchedResultsChangeUpdate event of NSFetchedResultsController
问题描述
我有一个 UITableView
使用 NSFetchedResultsController
作为数据源。
核心数据存储在并行运行的多个后台线程中更新(每个线程使用自己的 NSManagedObjectContext
)。
主线程观察 NSManagedObjectContextDidSaveNotification
通知并更新其上下文 mergeChangesFromContextDidSaveNotification:
。
有时会发生 例如:获取结果控制器的结果集包含 但是获取的结果控制器现在只包含3个对象, 根据 我现在找到了我的问题的解决方案。在更新事件的情况下,不需要调用 因此,我替换了 代码看起来像这样: I have a The core data store is updated in multiple background threads running in parallel (each thread using it's own The main thread observes the Sometimes it happens that the 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: But the fetched results controller contains only 3 objects now, and if call to update the table view cell according to the 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 because the updated object is already supplied as the anObject parameter to the I have therefore replaced The code looks now like this:
这篇关于NSFetchedResultsController的NSFetchedResultsChangeUpdate事件中的NSRangeException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! NSFetchedResultsController
发送
NSFetchedResultsChangeUpdate
b $ b 1节带4个对象。第一个对象在一个线程中被删除。
最后一个对象在不同的线程中更新。然后有时
会发生:
type = NSFetchedResultsChangeDelete,indexPath.row = b $ b type = NSFetchedResultsChangeUpdate,indexPath.row = 3。
MyManagedObject * obj = [controller objectAtIndexPath:indexPath]
NSFetchedResultsChangeUpdate
事件更新表视图单元格时,会与<$ c $感谢您的任何帮助或想法!
[self.controller objectAtIndexPath:indexPath]
因为更新的对象已作为,所以
< >
-configureCell:atIndexPath:
通过直接使用更新的对象的 -configureCell:withObject:
方法。这似乎工作没有问题。
- (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;
/ * ... * /
}
}
UITableView
that uses an NSFetchedResultsController
as data source.NSManagedObjectContext
).NSManagedObjectContextDidSaveNotification
notification and updates it's context with mergeChangesFromContextDidSaveNotification:
.NSFetchedResultsController
sends an
NSFetchedResultsChangeUpdate
event with an indexPath that does not exist
anymore at that point.
MyManagedObject *obj = [controller objectAtIndexPath:indexPath]
NSFetchedResultsChangeUpdate
event, this crashes with a NSRangeException
exception.[self.controller objectAtIndexPath:indexPath]
-controller:didChangedObject:...
delegate.-configureCell:atIndexPath:
by a -configureCell:withObject:
method that uses the updated object directly. This seems to work without problems.- (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;
/* ... */
}
}