嵌套的NSManagedObjectContext&NSFetchedResultsController用于关系

时间:2014-03-21 13:23:05

标签: objective-c core-data nsmanagedobjectcontext magicalrecord nsfetchedresultscontroller

尝试使用MagicalRecord按钮保存和取消,为我的CoreData实体实现添加/保存控制器。

- (void)addProduct
{
    NSManagedObjectContext *context = [NSManagedObjectContext MR_context];

    [context MR_setWorkingName:@"PRODUCT_ADD_MOC"];

    ProductBaseEntity *entity = [ProductBaseEntity MR_createInContext:context];
    [self presentProductSaveControllerWithEntity:entity andContext:context];
}

- (void)editProduct:(ProductBaseEntity *)entity
{
    [self presentProductSaveControllerWithEntity:entity andContext:nil];
}

- (void)presentProductSaveControllerWithEntity:(ProductBaseEntity *)entity
                                    andContext:(NSManagedObjectContext *)parentContext
{
    if (!parentContext) {
        parentContext = [NSManagedObjectContext MR_contextForCurrentThread];
    }

    NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithParent:parentContext];
    [context MR_setWorkingName:@"PRODUCT_SAVE_MOC"];

    ProductBaseEntity *contextEntity = (ProductBaseEntity *)[context objectWithID:entity.objectID];

    ProductSaveController *controller = [[ProductSaveController alloc] initWithEntity:contextEntity];

    controller.managedObjectContext = context;

    controller.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cancel"
                                                                                   style:UIBarButtonItemStylePlain
                                                                                  target:controller
                                                                                  action:@selector(cancel)];

    controller.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save"
                                                                                    style:UIBarButtonItemStylePlain
                                                                                   target:controller
                                                                                   action:@selector(done)];

    [controller setDoneHandler:^(ProductSaveController *saveController) {
        if (context.hasChanges) {
            [context MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
                [self dismissViewControllerAnimated:YES completion:nil];
            }];
        } else {
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }];

    [controller setCancelHandler:^(ProductSaveController *saveController) {
        if (context.hasChanges) {
            [OHAlertView showAlertWithTitle:@"Really exit?"
                                    message:@"Exit and discard changes?"
                               cancelButton:@"Cancel"
                                   okButton:@"Exit"
                             onButtonTapped:^(OHAlertView *alert, NSInteger buttonIndex) {
                                 if (buttonIndex == 1) {
                                     [self dismissViewControllerAnimated:YES completion:nil];
                                 }
                             }];
        } else {
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }];

    [self presentViewController:[[UINavigationController alloc] initWithRootViewController:controller] animated:YES completion:nil];
}

问题的第一部分是:这个实现看起来不错吗?我为保存控制器创建了分离的上下文,之后我可以决定:我应该保存持久存储中的更改(保存按钮)还是我应该抛弃更改而不修改持久存储(取消按钮)。对于addProduct,我再创建一个上下文,因为如果我调用context.hasChanges它会给我YES,因为对象已插入到此上下文中。

顺便说一句,这部分代码工作得非常好。

ProductSaveController我有一个按钮,使用SomeController打开ProductBaseEntity与[{1}}实体(1:M)相关的列表ProductEntity

NSFetchedResultsController

其中_fetchedResultsController = [ProductEntity MR_fetchAllSortedBy:@"position" ascending:YES withPredicate:predicate groupBy:nil delegate:self inContext:self.managedObjectContext]; 是来自self.managedObjetContext方法的上下文。问题是我的控制器没有反映该控制器的变化。例如我做:

presentProductSaveControllerWithEntity

我一无所有! tableView中的这一行并不隐藏!但如果我点击后退按钮并再次打开此控制器,我会看到变化!如果我从- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { ProductEntity *entity = [_fetchedResultsController objectAtIndexPath:indexPath]; [entity MR_deleteInContext:_fetchedResultsController.managedObjectContext]; } } 移动到mainQueue上下文,我的fetchedResultsController按预期工作。 NSFetchedResultsController是否应该使用私有队列上下文??

1 个答案:

答案 0 :(得分:0)

您正在删除该实体,但您似乎没有回复删除和更新您的视图。您通常可以通过在视图控制器上实现NSFetchedResultsControllerDelegate来实现此目的