iOS核心数据 - 将上下文传递给细节视图的设计模式

时间:2010-10-27 04:27:25

标签: iphone core-data ios

我有点难以接受一个问题,我认为这可以追溯到我的设计。

我正在构建一个基于静态行集(4)的TableViewController - 使用它作为UITableView的基础。每一行都会启动不同的视图(详细信息和UITableViews)......在顶层视图的托管对象上下文中,我可以轻松导航到相关的详细信息视图,因为它位于上下文中(昵称)..我最初只是考虑过不相关的表格和一系列按钮会触发视图...但我抛弃了这个想法。我当前的主要问题是知道如何切换MOC或不同的fetchedresults控制器(按照每个.m中定义的方式从不同的表中获取。

目前,我在TableViewControler.m中有一个开关..这个片段有效:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSInteger switchval = indexPath.row;

    switch (switchval) {
     case 0: // Nickname 
     {
       //This version brings up a detailed view controller - 
      NickNameDetail *controller = [[NickNameDetail alloc] initWithNibName:@"NickNameDetail" bundle:nil];
      controller.fetchedResultsController = self.fetchedResultsController;
      controller.managedObjectContext = [self.fetchedResultsController objectAtIndexPath:indexPath];
      [self.navigationController pushViewController:controller animated:YES];
      break;  
     }
     case 1:  
     {      
      //NextTableViewContoller *.... (etc)... here here
    ...

但是,我无法弄清楚如何切换到不同的上下文并获得不同的行。

meTableViewController.managedObjectContext = self.managedObjectContext;
nickNameDetail.managedObjectContext = self.managedObjectContext;
nextTableViewController.managedObjectContext = self.managedObjectContext;

之前有人遇到过这样的情景吗?抱歉,无法让代码格式化程序表现出来。

谢谢!

1 个答案:

答案 0 :(得分:2)

在某些情况下,将当前视图控制器的MOC传递给在导航堆栈上推送的新视图控制器可能是好的/适当的。但是,您通常希望传递新创建的MOC。这样做如下:

在你的app delegate中添加以下方法

- (NSManagedObjectContext*)createNewManagedObjectContext
{

    NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init]; 
    [moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; 
    return [moc autorelease];
}
视图控制器中的

按如下方式传递MOC

myAppDelegate *mainDelegate = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainMOC = [mainDelegate createNewManagedObjectContext]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) 
                                                         name:NSManagedObjectContextDidSaveNotification
                                                       object:mainMOC];

newViewController.managedObjectContext = mainMOC;

然后根据需要处理通知,这是一个示例

- (void)contextDidSave:(NSNotification *)notification
{

    [managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
    [self.tableView reloadData];

}

您还需要为每个视图控制器定义和使用不同的NSFetchedResultsController。这是因为您要获取和显示的数据当然对于每个视图控制器(不同的实体,谓词等)是不同的。只需在每个实现文件中定义它们。这是一个例子:

- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    /*
     Set up the fetched results controller.
     */

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Context" inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];

    if(self.project){
        // get the contexts for the project
        NSPredicate * predicate = [NSPredicate predicateWithFormat: @"projectName == %@", self.project.name];
        [request setPredicate:predicate];
    }

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [request 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:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [request release];
    [sortDescriptor release];
    [sortDescriptors release];

    return fetchedResultsController;
}    

然后根据需要使用fetchedResultsController。例如,将其放在viewDidLoad方法中:

    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }