uitableview - 如何以编程方式填充核心数据存储?

标签 uitableview core-data crash

编辑:可以从 crashTest 下载一个显示崩溃的最小项目.它是通过在 XCode 中选择“基于核心数据的导航”项目模板并修改可能十行来创建的。

当一次添加一个部分和两个对象时,我的头发已经用完了。

崩溃发生在对 [managedObjectContext save:&error] 的调用内的例程结束时。 .

崩溃是 NSArray 的越界异常。 :

Serious application error.  Exception was caught during Core Data change processing: *** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (1) with userInfo (null)

也可能相关,当异常发生时,我的获取结果 Controller controllerDidChangeContent:委托(delegate)例程在调用堆栈中。它只是调用我的 TableView endUpdate常规。

我现在没有想法了。我应该如何使用部分将多个项目插入到具有 TableView 的核心数据存储中?

这是调用堆栈:
#0  0x901ca4e6 in objc_exception_throw
#1  0x01d86c3b in +[NSException raise:format:arguments:]
#2  0x01d86b9a in +[NSException raise:format:]
#3  0x00072cb9 in _NSArrayRaiseBoundException
#4  0x00010217 in -[NSCFArray objectAtIndex:]
#5  0x002eaaa7 in -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:]
#6  0x002def02 in -[UITableView endUpdates]
#7  0x00004863 in -[AirportViewController controllerDidChangeContent:] at AirportViewController.m:463
#8  0x01c43be1 in -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:]
#9  0x0001462a in _nsnote_callback
#10 0x01d31005 in _CFXNotificationPostNotification
#11 0x00011ee0 in -[NSNotificationCenter postNotificationName:object:userInfo:]
#12 0x01ba417d in -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:]
#13 0x01c03763 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:]
#14 0x01b885ea in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:]
#15 0x01bbe728 in -[NSManagedObjectContext save:]
#16 0x000039ea in -[AirportViewController populateAirports] at AirportViewController.m:112

这是例程的代码。我很抱歉,因为许多行可能无关紧要,但我宁愿在这方面犯错。调用 [context save:&error] 时发生崩溃:
- (void) insertObjects
{
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[fetchedResultsController fetchRequest] entity];

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

// If appropriate, configure the new managed object.
[newManagedObject setValue:@"new airport1" forKey:@"name"];
[newManagedObject setValue:@"???" forKey:@"code"];
[newManagedObject setValue:@"new country" forKey:@"country_name"];

newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newManagedObject setValue:@"new airport2" forKey:@"name"];
[newManagedObject setValue:@"???" forKey:@"code"];
[newManagedObject setValue:@"new country" forKey:@"country_name"];


// Save the context.
NSError *error = nil;
if (![context save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}
}

注意:这些部分是由 country_name .此外,四个 NSFetchedResultsControllerDelegate例程由 XCode 记录和预设:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
       atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
    case NSFetchedResultsChangeInsert:
        [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
        break;
// other cases omitted because not occurring in this crash            

}
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;

switch(type) {

    case NSFetchedResultsChangeInsert:
        [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
// other cases omitted because not occurring in this crash            
}
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}

最佳答案

在我看来,这是 Cocoa Touch 中的一个错误。我当然可能是错的。无论如何,我找到了解决方法。

解决方法包括在四个委托(delegate)例程中什么都不做,但仅在这种情况下。我最终添加了 BOOL massUpdate我在添加对象之前设置为 true 并在调用保存后重置为 false 的 iVar。

在四个委托(delegate)例程中,我测试了 massUpdate iVar。如果这是真的,我什么都不做,除了在第四个中,我重新加载整个表格 View 。

我得到:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
if (massUpdate)
    return;
[self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
       atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
if (massUpdate)
    return;
    <snip normal implementation>
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath
{
if (massUpdate)
    return;
    <snip normal implementation>
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
if (massUpdate)
    [self.tableView reloadData];
else
    [self.tableView endUpdates];
}

关于uitableview - 如何以编程方式填充核心数据存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2444327/

相关文章:

iPhone核心数据轻量级迁移: Can't merge models

ios - 在 CoreData 中存储 NSMutableAttributedString 的简单方法

ios - 当我开始构建带有此错误消息的应用程序时,它崩溃了。这是什么意思?

ios - 使用 "more"按钮像 Instagram 一样在 UITableView 中扩展 UILabel

ios - 使用自定义单元格在 UITableView 上进行多点触控

ios - 如何使 scrollView 像 Apple AppStore "Featured Page"一样?

ios - 如何在添加到 XIB 中 UItableviewcontroller 的 tableview 中配置 tableviewcell?

ios - Swift CoreData 到 UICollectionView

ios - 当系统清除内存并关闭 UIViewController 时 iOS 崩溃

iphone - Phonegap 1.2在iPhone 3G iOS 3.x上不起作用