iOS-如何传递AppDelegate';将ManagedObjectContext添加到来自NavigationView的UIViewController

iOS-如何传递AppDelegate';将ManagedObjectContext添加到来自NavigationView的UIViewController,ios,iphone,objective-c,core-data,Ios,Iphone,Objective C,Core Data,我正在为核心数据概念而挣扎,我需要一些澄清 我正在使用故事板,我有2个视图。第一个视图嵌入在导航控制器中,第二个视图只是来自模态segue的UIViewController。 在AppDelegate中,我使用以下代码将managedObjectContext传递给第一个视图: UINavigationController *nav = (UINavigationController *) self.window.rootViewController; JobListTableViewContr

我正在为核心数据概念而挣扎,我需要一些澄清

我正在使用故事板,我有2个视图。第一个视图嵌入在导航控制器中,第二个视图只是来自模态segue的UIViewController。 在AppDelegate中,我使用以下代码将managedObjectContext传递给第一个视图:

UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
JobListTableViewController *jltvc = (JobListTableViewController *)[[nav viewControllers]objectAtIndex:0];
jltvc.managedObjectContext = self.managedObjectContext;
问题是,现在我还需要将managedObjectContext从AppDelegate传递到第二个视图,但我不知道如何获取它。 由于没有索引1,执行此操作将失败:

AddJobsViewController *ajvc = (AddJobsViewController *)[[nav viewControllers]objectAtIndex:1];
我无法发布我的故事板截图,因为我没有足够的声誉:(

在此核心数据/授权问题上的任何帮助都将不胜感激。
谢谢。

在您的作业列表表视图控制器添加作业视图控制器中,您可以像这样保存AppDelegate的引用

#import "AppDelegate.h"


AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate];
jltvc.managedObjectContext = app.managedObjectContext;

我的建议是,不要从视图控制器传递上下文。相反,创建新上下文并从新上下文中获取实体。传递相同上下文的缺点是,如果在两个不同的位置修改了相同的实体,则必须管理合并冲突。上下文就像一个废纸片,可以由我们来处理如果您不想更改,请尝试进行更改并保存或放弃上下文。因此,您可以在每次需要修改实体时创建本地上下文,并根据需要保存或放弃上下文,从而避免冲突。 我更喜欢这样的三层体系

-(NSManagedObjectContext*) backgroundMasterContext // this context is used to save data in core data
{
    if(!_backgroundMasterContext) {
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if(coordinator) {
            _backgroundMasterContext =  [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
            [_backgroundMasterContext setPersistentStoreCoordinator:coordinator];
        }
    }
    return _backgroundMasterContext;
}

-(NSManagedObjectContext*) mainContext // this context is a read only context which is used everytime you want to read the entities
{
    if (!_mainContext) {
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator) {
            _mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
            [_mainContext setParentContext:self.backgroundMasterContext];
        }
    }

    return _mainContext;
}

-(NSManagedObjectContext*) createWriteContext // this context is used everytime you want to edit an entity 
{
    NSManagedObjectContext *newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [newContext setParentContext:self.mainContext];
    return newContext;
}
为了节省时间,我称之为这个方法

- (void) saveAllWithContext:(NSManagedObjectContext*) writeContext
                    success:(DMSuccessBlock)success
                    failure:(DMFailureBlock)failure
{
    BOOL b = NO;
    NSError *error = nil;
    if([writeContext hasChanges]) {
        b=[writeContext save:&error];

        if(b) {
            NSManagedObjectContext *parentContext = [writeContext parentContext];
            if(parentContext) {
                [parentContext performBlock:^{
                    [self saveAllWithContext:parentContext success:success failure:failure];
                }];
            } else {
                if(success)
                    success();
            }
        } else {
            if(failure)
                failure(error);
        }
    }
    else {
        if(success)
            success();
    }
}
此方法更新主上下文和后台主上下文


希望有帮助:)

Thanx。我在好几个地方读过这个选项,我看到了各种各样的答案。有人说这是一种很棒的设计方法,也有人说这是一种糟糕的做法。您是否知道这种方法的缺点是什么,或者为什么有些人讨厌它?频繁访问AppDelegate可能是一个问题。但如果未加载,则可以在JLTVC或AJVC中创建私有AppDelegate变量。这种方法没有什么不好的。好的,谢谢。那我就用那种方法。