ios - 核心数据错误 : nil is not a legal NSManagedObjectContext parameter

标签 ios objective-c ipad core-data

我对创建 iOS 应用程序完全陌生。我必须快速创建一个表单应用程序,我可以在其中存储愿意填写的人的信息。基本上只是一堆用于名称、邮件等内容的文本字段。

填写表格后,我将使用以下代码存储他们的数据:

//Save action
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Person" inManagedObjectContext: context];
NSManagedObject *newPerson = [[NSManagedObject alloc]initWithEntity:entityDesc insertIntoManagedObjectContext:context];

//Fill in values
[newPerson setValue:self.btnPrefix.titleLabel.text forKey: @"prefix"];
[newPerson setValue:self.txtFirstName.text forKey: @"firstname"];
[newPerson setValue:self.txtLastName.text forKey: @"lastname"];
[newPerson setValue:self.txtLive.text forKey: @"country"];
[newPerson setValue:self.txtMail.text forKey: @"email"];
[newPerson setValue:self.txtPhone.text forKey: @"phonenumber"];
[newPerson setValue:self.txtLinked.text forKey: @"linkedIn"];
[newPerson setValue:self.txtAbout.text forKey: @"about"];

NSError *error;
[context save:&error];

在模拟器上执行时完全没有问题。但是一旦在 iPad 上运行,我就会得到这个错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Person''



调试后它会在第一行触发:
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Person" inManagedObjectContext: context];

经过一番研究,我的 Appdelegate 在设备上运行时包含一个 nil persistentContainer,但在虚拟设备上运行时它已被填充。所以我想问题就在那里,但我找不到解决方法。
- (void)viewDidLoad {
    [super viewDidLoad];
    AppDelegate *appdelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
    context = appdelegate.persistentContainer.viewContext;
}

谁能帮我吗?

最佳答案

对于那些遇到此错误的人。如果它在虚拟设备上工作但在物理设备上不工作,很可能是由于 iOS 9 和 10 之间访问核心数据的差异。

在 Xcode 8 中,AppDelegate 会自动为 iOS 10 生成数据,但如果您卡在 iOS 9 上,则需要在您的委托(delegate)文件中添加以下代码:

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (NSURL *) applicationDocumentsDirectory{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSManagedObjectModel *)managedObjectModel {
    if(_managedObjectModel != nil){
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"StylelabsForms" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *) persistentStoreCoordinator{
    if(_persistentStoreCoordinator != nil){
        return _persistentStoreCoordinator;
    }

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"StylelabsForms.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"Error loading saved data";
    if(![_persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType configuration:nil URL: storeURL options:nil error:&error]){
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed init application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _persistentStoreCoordinator;
}

- (NSManagedObjectContext *) managedObjectContext {
    if (_managedObjectContext != nil){
        return _managedObjectContext;
    }

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

    return _managedObjectContext;
}

同时调整保存如下:
- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if(managedObjectContext != nil){
        NSError *error = nil;
        if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]){
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }

    //For iOS 10 and above
    /*
    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();
    } */
}

关于ios - 核心数据错误 : nil is not a legal NSManagedObjectContext parameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44051593/

相关文章:

ios - 在 UITextField 中的文本下方添加 "padding"| swift

iphone - ViewController 在 iOS6 上不旋转

iphone - iOS 识别用户

iphone - 如何测量 UIImageView 的绘制时间?

css - 在 Firefox、iPad 和 Safari 上快速滚动会导致元素消失然后重新出现

ios - 比较 NSURL 字符串和简单的 Swift 字符串

ios - 钥匙串(keychain)集 - NoSuchAttribute - 为什么?

ios - 循环字典中的特定键以获取值

ios - 使用 CoreGraphics 创建多页 PDF 文件在控制台上显示错误

ios - 返回更高级别的 UITableView 时的 ViewDidLoad