【问题标题】:CoreData NSManagedObjectContext not found未找到 CoreData NSManagedObjectContext
【发布时间】:2017-05-23 05:45:26
【问题描述】:

iOS 开发新手。我正在尝试在示例应用程序中使用核心数据堆栈,该应用程序通过网络获取数据并简单地更新 UI。在创建项目时,勾选了“使用核心数据”复选框,这会生成一堆样板代码。但是,在XCode 8.2.1 上,我只看到AppDelegate.m 文件中的NSPersistentContainer 实现。

- (NSPersistentContainer *)persistentContainer {
    // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
    @synchronized (self) {
        if (_persistentContainer == nil) {
            _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"ergast_coredata_objc"];
            [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
                if (error != nil) {
                    // Replace this implementation with code to handle the error appropriately.
                    // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                    /*
                     Typical reasons for an error here include:
                     * The parent directory does not exist, cannot be created, or disallows writing.
                     * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                     * The device is out of space.
                     * The store could not be migrated to the current model version.
                     Check the error message to determine what the actual problem was.
                    */
                    NSLog(@"Unresolved error %@, %@", error, error.userInfo);
                    abort();
                }
            }];
        }
    }

    return _persistentContainer;
}

NSManagedObjectContext 没有样板代码,因为大多数教程会让您相信。

因此,ViewController.m 类中的以下块失败,由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[AppDelegate managedObjectContext]: unrecognized selector sent to instance

-(NSArray *)getSeasonsList{
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SeasonData"];
    NSError *error = nil;
    NSArray *results = [[self getManagedObjectContext] executeFetchRequest:request error:&error];
    if (!results) {
        NSLog(@"Error fetching objects: %@\n%@", [error localizedDescription], [error userInfo]);
        abort();
    }
    return results;
}




- (NSManagedObjectContext *)getManagedObjectContext {
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    context = [delegate managedObjectContext];
    return context;

}

尝试在网上查找,但大多数教程似乎都是基于 Swift 的。我在这里想念什么?开发人员是否应该为NSManagedObjectContext 提供实现?如果有人可以提供基于 Objective-c 的示例代码,将不胜感激。

谢谢!

【问题讨论】:

  • 我认为您在差异视图控制器中从 appDelegate 访问 managedObjectContext,即使您没有在 appDelegate 接口中公开 getManagedObjectContext

标签: objective-c xcode core-data nsmanagedobjectcontext


【解决方案1】:

saveContext方法

pragma mark - 核心数据保存支持

- (void)saveContext {
    // OBSERVE HERE
    NSManagedObjectContext *context = self.persistentContainer.viewContext; 
    NSError *error = nil;
    if ([context hasChanges] && ![context save:&error]) {
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, error.userInfo);
        abort();
    }
}

当你需要 NSManagedObjectContext 实例时,像这样访问

NSManagedObjectContext *context = self.persistentContainer.viewContext;

self.persistentContainer classObject.persistentContainer

【讨论】:

    【解决方案2】:

    修改“getManagedObjectContext”方法如下

    - (NSManagedObjectContext *)getManagedObjectContext {
        AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        NSManagedObjectContext *context = [[delegate persistentContainer] viewContext];
        return context;
    }
    

    我没有测试这个,但希望这能工作

    【讨论】:

      【解决方案3】:

      我有一个 appdelegate 类别,它包含在一个使用 Objective-c 的旧斯坦福 CS193P 中。不过,其中一些可能已被弃用。另请查看https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/InitializingtheCoreDataStack.html#//apple_ref/doc/uid/TP40001075-CH4-SW1 有objective-c 示例。如果有帮助,请回帖。

      //
      //  PhotomaniaAppDelegate+MOC.m
      //  Photomania
      //
      //  This code comes from the Xcode template for Master-Detail application.
      
      #import "PhotomaniaAppDelegate+MOC.h"
      #import <CoreData/CoreData.h>
      
      @implementation PhotomaniaAppDelegate (MOC)
      
      #pragma mark - Core Data
      
      - (void)saveContext:(NSManagedObjectContext *)managedObjectContext
      {
          NSError *error = nil;
          if (managedObjectContext != nil) {
              if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
                  // Replace this implementation with code to handle the error appropriately.
                  // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                  abort();
              }
          }
      }
      
      // Returns the managed object context for the application.
      // If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
      - (NSManagedObjectContext *)createMainQueueManagedObjectContext
      {
          NSManagedObjectContext *managedObjectContext = nil;
          NSPersistentStoreCoordinator *coordinator = [self createPersistentStoreCoordinator];
          if (coordinator != nil) {
              managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
              [managedObjectContext setPersistentStoreCoordinator:coordinator];
          }
          return managedObjectContext;
      }
      
      // Returns the managed object model for the application.
      // If the model doesn't already exist, it is created from the application's model.
      - (NSManagedObjectModel *)createManagedObjectModel
      {
          NSManagedObjectModel *managedObjectModel = nil;
          NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Photomania" withExtension:@"momd"];
          managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
          return managedObjectModel;
      }
      
      // Returns the persistent store coordinator for the application.
      // If the coordinator doesn't already exist, it is created and the application's store added to it.
      - (NSPersistentStoreCoordinator *)createPersistentStoreCoordinator
      {
          NSPersistentStoreCoordinator *persistentStoreCoordinator = nil;
          NSManagedObjectModel *managedObjectModel = [self createManagedObjectModel];
      
          NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MOC.sqlite"];
      
          NSError *error = nil;
          persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
          if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
              /*
               Replace this implementation with code to handle the error appropriately.
      
               abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
      
               Typical reasons for an error here include:
               * The persistent store is not accessible;
               * The schema for the persistent store is incompatible with current managed object model.
               Check the error message to determine what the actual problem was.
      
      
               If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
      
               If you encounter schema incompatibility errors during development, you can reduce their frequency by:
               * Simply deleting the existing store:
               [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
      
               * Performing automatic lightweight migration by passing the following dictionary as the options parameter:
               @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
      
               Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
      
               */
              NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
              abort();
          }
      
          return persistentStoreCoordinator;
      }
      
      // Returns the URL to the application's Documents directory
      
      - (NSURL *)applicationDocumentsDirectory
      {
          return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
      }
      
      @end
      

      另外,请查看此项目https://github.com/m2mtech/photomania-2013-14/tree/master/Photomania/CoreDataTableViewController/MOC 了解如何在此实现中使用 Core Data。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-05
        • 1970-01-01
        • 2014-12-09
        • 2020-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多