【问题标题】:iOS - How to Pass AppDelegate's ManagedObjectContext to UIViewController that comes from NavigationViewiOS - 如何将 AppDelegate 的 ManagedObjectContext 传递给来自 NavigationView 的 UIViewController
【发布时间】:2023-03-30 15:55:02
【问题描述】:

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

我正在使用 Storyboard,我有 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];

我无法发布我的故事板的屏幕截图,因为我没有足够的 stackoverflow 声誉:(

我们将不胜感激任何有关此核心数据/委托问题的帮助。 谢谢。

【问题讨论】:

    标签: ios iphone objective-c core-data


    【解决方案1】:

    在您的 JobListTableViewControllerAddJobsViewController 中,您可以像这样持有 AppDelegate 的引用。

    #import "AppDelegate.h"
    
    
    AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    jltvc.managedObjectContext = app.managedObjectContext;
    

    【讨论】:

    • 谢谢。我已经在几个地方阅读了该选项,并且看到了不同的答案。有人说这是一种很好的设计方法,也有人说这是不好的做法。您是否知道这种方法的缺点或为什么有些人讨厌它?
    • 频繁访问 AppDelegate 可能是一个问题。但是如果没有加载,那么您可以在 JLTVC 或 AJVC 中创建私有 AppDelegate 变量。这种方法有一点不好。
    • 好的,谢谢。那我就用那个方法。
    【解决方案2】:

    我给你的建议是不要从视图控制器传递上下文。而不是创建一个新的上下文并从新的上下文中获取实体。传递相同上下文的缺点是,如果在两个不同的地方修改了相同的实体,则必须管理合并冲突。上下文就像一个废纸垫,可用于进行更改和保存,或者如果您不想要更改则丢弃上下文。因此,您可以在每次要修改实体时创建本地上下文,并根据需要保存或丢弃它,从而避免冲突。 我更喜欢这样的 3 层系统

    -(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();
        }
    }
    

    此方法更新主上下文和后台主上下文。

    希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-28
      • 1970-01-01
      • 2014-11-06
      • 2020-10-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多