【问题标题】:managedObjectContext is nilmanagedObjectContext 为零
【发布时间】:2012-04-10 02:42:20
【问题描述】:

我正在尝试将 Core Data 添加到现有项目中。我已经:

1) 添加了核心数据框架 2)将访问器和属性添加到 AppDelegate 3)创建数据模型文件

现在当我尝试打电话时 NSManagedObjectContext *context = [self managedObjectContext]; 从视图控制器来看,上下文为 nil,并且 managedObjectContext 永远不会触发。

这是 AppDelegate:

#import "XXXAppDelegate.h"
#import <CoreData/CoreData.h>

@implementation XXXAppDelegate 

@synthesize window=_window;
@synthesize navigationController=_navigationController;
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    // Add the navigation controller's view to the window and display.
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];

    return YES;
}

// Explicitly write Core Data accessors
- (NSManagedObjectContext *) managedObjectContext {
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }

    return managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

    return managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
                                               stringByAppendingPathComponent: @"<Project Name>.sqlite"]];
    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
                                  initWithManagedObjectModel:[self managedObjectModel]];
    if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                 configuration:nil URL:storeUrl options:nil error:&error]) {
        /*Error for store creation should be handled in here*/
    }

    return persistentStoreCoordinator;
}

- (NSString *)applicationDocumentsDirectory {
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

@end

编辑:这是我的视图控制器代码

NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *cardSet = [NSEntityDescription insertNewObjectForEntityForName:@"CardSet" inManagedObjectContext:context];
[cardSet setValue:@"Set 1" forKey:@"cardSetName"];

【问题讨论】:

  • 你的managedObjectContext nil 是从哪里得到的?在 Appdelegate.m 或其他类中?

标签: ios core-data xcode4


【解决方案1】:

尝试添加这些条件以检查您的 managedObjectContext 是否为 nil 或不在您想要使用的任何位置。如果是nil,则从Appdelegate 文件中复制它。

 if (managedObjectContext == nil) 
 { 
    managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    NSLog(@"After managedObjectContext: %@",  managedObjectContext);
 }

【讨论】:

    【解决方案2】:

    假设您的属性已声明...您正在将它们合成为 ivars,前面带有下划线。这是好事。但是,唯一 您想用下划线访问它们的地方是在属性的 getter/setter 的实现中。不幸的是,这些都没有发生。改成...

    - (NSManagedObjectContext *) managedObjectContext {
        if (_managedObjectContext != nil) {
            return _managedObjectContext;
        }
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            _managedObjectContext = [[NSManagedObjectContext alloc] init];
            [_managedObjectContext setPersistentStoreCoordinator: coordinator];
        }
    
        return _managedObjectContext;
    }
    
    - (NSManagedObjectModel *)managedObjectModel {
        if (_managedObjectModel != nil) {
            return _managedObjectModel;
        }
        _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    
        return _managedObjectModel;
    }
    
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
        if (_persistentStoreCoordinator != nil) {
            return _persistentStoreCoordinator;
        }
        NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
                                                   stringByAppendingPathComponent: @"<Project Name>.sqlite"]];
        NSError *error = nil;
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
                                      initWithManagedObjectModel:[self managedObjectModel]];
        if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                     configuration:nil URL:storeUrl options:nil error:&error]) {
            /*Error for store creation should be handled in here*/
        }
    
        return _persistentStoreCoordinator;
    }
    

    【讨论】:

      【解决方案3】:

      如果您查看 Xcode 中的 Master-Detail Application 模板,您会看到它们在 AppDelegate 中传递 ManagedObjectContext,如下所示:

      #import "AppDelegate.h"
      
      #import "MasterViewController.h"
      
      @implementation AppDelegate
      
      @synthesize managedObjectContext = _managedObjectContext;
      @synthesize managedObjectModel = _managedObjectModel;
      @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
      
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          // Override point for customization after application launch.
          UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
          MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
          NSLog(@"navigationController viewControllers: %@",[navigationController viewControllers]);
          NSLog(@"navigationController.topViewController: %@",navigationController.topViewController);
      
          controller.managedObjectContext = self.managedObjectContext;
          return YES;
      }
      

      如果您的应用前面需要一个 TabBarViewController,代码如下所示:

      #import "AppDelegate.h"
      
      #import "MasterViewController.h"
      
      @implementation AppDelegate
      
      @synthesize managedObjectContext = _managedObjectContext;
      @synthesize managedObjectModel = _managedObjectModel;
      @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
      
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          // Override point for customization after application launch.
          UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
      
          UINavigationController *navigationController = (UINavigationController *)[[tabController viewControllers] objectAtIndex:0];
          MasterViewController *controller = (MasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
          controller.managedObjectContext = self.managedObjectContext;
      
          navigationController = (UINavigationController *)[[tabController viewControllers] objectAtIndex:1];
          controller = (MasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
          controller.managedObjectContext = self.managedObjectContext;
      
          navigationController = (UINavigationController *)[[tabController viewControllers] objectAtIndex:2];
          controller = (MasterViewController *)[[navigationController viewControllers] objectAtIndex:0];
          controller.managedObjectContext = self.managedObjectContext;
      
          return YES;
      }
      

      【讨论】:

        【解决方案4】:

        我不知道你是如何在没有编译器错误的情况下过去的,但你的 @synthesizes 使用了你的 getter 永远不会访问的带下划线的变量。这样做:

        - (NSManagedObjectContext *) managedObjectContext {
            if (_managedObjectContext != nil) {
                return _managedObjectContext;
            }
            NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
            if (coordinator != nil) {
                _managedObjectContext = [[NSManagedObjectContext alloc] init];
                [_managedObjectContext setPersistentStoreCoordinator: coordinator];
            }
        
            return _managedObjectContext;
        }
        

        注意_managedObjectContext(带下划线)。对 managedObjectModelpersistentStoreCoordinator 执行相同的修复。

        【讨论】:

        • 感谢您的回复。试过这个,但仍然没有运气。我已将视图控制器中的代码添加到上面的主帖中。
        • 您是否尝试过使用断点调试代码以查看执行是否完全进入您的 getter?
        • self.managedObjectContext 对我不起作用。 _managedObjectContext 工作。但我不知道怎么做。在我的 AppDelegate.h 文件中,我有一个属性 managedObjectContext。 _managedObjectContext 是从哪里来的?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多