managedObjectModel 为零(仅在 WatchApp 中)

Posted

技术标签:

【中文标题】managedObjectModel 为零(仅在 WatchApp 中)【英文标题】:managedObjectModel in nil ( only in WatchApp ) 【发布时间】:2015-01-05 16:47:45 【问题描述】:

我正在为 Apple Watch 更新应用 这个应用程序使用 coredata,所以我创建了一个框架来管理核心数据堆栈! 当我在设备或模拟器上运行应用程序时,应用程序工作正常,但是当我在 Apple Watch 模拟器上运行它时,应用程序崩溃并显示此日志

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无法创建 NSPersistentStoreCoordinator 与 nil 模型'

问题似乎是 managedObjectModel,如果我记录它

NSLog(@"managedObjectModel %@", _managedObjectModel);

日志返回

managedObjectModel (null)

框架中的代码看起来正确,实际上主应用程序运行良好

反正这是框架的内容

#import "DataAccess.h"

@implementation DataAccess

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


+ (instancetype)sharedInstance

    static DataAccess *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        sharedInstance = [[DataAccess alloc] init];
        // Do any other initialisation stuff here
    );
    return sharedInstance;


- (void)saveContext

    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    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();
        
    




#pragma mark - Core Data stack

// 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 *)managedObjectContext

    if (_managedObjectContext != nil) 
        return _managedObjectContext;
    

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) 
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_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 *)managedObjectModel

    if (_managedObjectModel != nil) 

        NSLog(@"managedObjectModel %@", _managedObjectModel);

        return _managedObjectModel;

    
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    NSLog(@"managedObjectModel %@", _managedObjectModel);


    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 *)persistentStoreCoordinator

    if (_persistentStoreCoordinator != nil) 
        return _persistentStoreCoordinator;
    

    //NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TMM.sqlite"];
    //NSURL *storeURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory  inDomains:NSAllDomainsMask] lastObject];
//    storeURL = [storeURL URLByAppendingPathComponent:@"db.sqlite"];

    NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.ragazzetto.MyApp.Documents"];
    storeURL = [storeURL URLByAppendingPathComponent:@"MyApp.sqlite"];

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) 

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    

    return _persistentStoreCoordinator;

#pragma mark - Application's Documents directory

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory

    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];



@end

问题出在哪里?

感谢您的帮助

【问题讨论】:

【参考方案1】:

当您编写一个 ios 应用程序扩展时——包括所有当前的 WatchKit 应用程序——你正在创建一个单独的可执行文件和它自己的包。应用程序中的资源不一定在扩展程序中可用,反之亦然。所以当你这样做时:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

在 WatchKit 应用程序中运行时的 URL 与在您的包含应用程序中运行时的 URL 不同。该错误告诉您 WatchKit 应用的 URL 无效,即 WatchKit 应用的包中没有模型文件。

简单的解决方法是将模型包含在 WatchKit 包中。这样做:

    在 Xcode 中选择模型文件 打开 Xcode 窗口右侧的文件检查器面板 查看“目标成员”部分。确保您的 WatchKit 目标已被选中。

这应该可以,但意味着您有两个模型文件副本。更好的方法是将模型文件放入两个目标都使用的共享框架中。这有点复杂,但稍微搜索一下就会找到详细的步骤。

【讨论】:

感谢汤姆的帮助!

以上是关于managedObjectModel 为零(仅在 WatchApp 中)的主要内容,如果未能解决你的问题,请参考以下文章

节点的几何(来自 DAE 文件)仅在生产版本中为零

managedObjectModel:initWithContentOfURL 中的错误

找不到 managedObjectModel

覆盖UIManagedDocument中的managedObjectModel

ManagedObjectModel 子类在 Swift 中不起作用

在 tableview 中显示图像时 managedObjectModel 错误指令