核心数据和UITableView实践/问题

时间:2011-12-28 14:36:07

标签: objective-c uitableview ios4 core-data ios5

我是iPhone编程的新手,也就是CoreData。我只是想知道一些一般做法和做事方式。

我正在尝试将CoreData中的实体添加/加载到UITableView。因此,在AppDelegate中,我在didfinishlaunchingwithoptions上加载NSArray实体(NSManagedObjects)并为我的表视图控制器填充NSArray。在表视图控制器中,然后使用NSManagedObjects的NSArray在cellForRowAtIndexPath方法中指定单元格视图。

这是最好的方法吗?我应该使用NSManagedObjects数组来加载它并使用添加/删除来管理该数组,还是应该通过循环获取并填充我创建的新类对象以分别表示每个单元格将包含的每个对象?

我不想做比需要更多的工作,但我也不想做任何不好的事情。

请帮助,非常感谢!

1 个答案:

答案 0 :(得分:8)

您的app委托应该只将其NSManagedObjectContext传递给您的表视图控制器,然后该控制器创建自己的NSFetchedResultsController实例,该类可以有效地加载托管对象以便在UITableView中显示并响应对象图中的变化。

Xcode 4.2中的“Master-Detail Application”核心数据项目模板使用此模式。这是一个很好的参考和起点。以下是主表视图控制器如何延迟加载和配置其结果控制器:

- (NSFetchedResultsController *)fetchedResultsController
{
    if (__fetchedResultsController != nil) {
        return __fetchedResultsController;
    }

    // Set up the fetched results controller.
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return __fetchedResultsController;
}

获得NSFetchedResultsController之后,只需将获取的对象插入表视图数据源方法即可,例如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = <#Get the cell#>;
    NSManagedObject *managedObject = [<#Fetched results controller#> objectAtIndexPath:indexPath];
    // Configure the cell with data from the managed object.
    return cell;
}

查看项目模板并阅读NSFetchedResultsController classNSFetchedResultsControllerDelegate protocol引用以了解详情。 Apple的文档包含完整的源代码示例。