将 CoreData 添加到现有项目后出错

Posted

技术标签:

【中文标题】将 CoreData 添加到现有项目后出错【英文标题】:Error after adding CoreData to existing project 【发布时间】:2014-09-03 18:17:29 【问题描述】:

我已将 CoreData 添加到我现有的项目中。我将 CoreData.framework 添加到 XCode 中的 Libs 中。 所以我的数据处理类是

进口

@interface UBCoreDataStack : NSObject

+(instancetype) defaultStack;

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

它的实现

#import "UBCoreDataStack.h"

@implementation UBCoreDataStack

@synthesize managedObjectModel;
@synthesize managedObjectContext;
@synthesize persistentStoreCoordinator;

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


//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;
    
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"UBFoodDeliveryModel" withExtension:@"momd"];
  //  managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return managedObjectModel;


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

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"UBFoodDelivery.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];


- (NSURL *)applicationStoresDirectory 


    NSURL *storesDirectory =
    [[NSURL fileURLWithPath:[self applicationDocumentsDirectory]]
     URLByAppendingPathComponent:@"Stores"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:[storesDirectory path]]) 
        NSError *error = nil;
        if ([fileManager createDirectoryAtURL:storesDirectory
                  withIntermediateDirectories:YES
                                   attributes:nil
                                        error:&error]) 

        
        else NSLog(@"FAILED to create Stores directory: %@", error);
    
    return storesDirectory;


+(instancetype) defaultStack
    static UBCoreDataStack * defaultStack;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        defaultStack = [[self alloc] init];
    );

    return defaultStack;


@end

但是现在当我尝试对数据库进行一些操作时,我总是在方法中遇到错误 NSURL *storeURL = [[self applicationDocumentsDirectory] ​​URLByAppendingPathComponent:@"UBFoodDelivery.sqlite"] ;

The error is 
2014-09-03 22:35:15.663 UBFoodDelivery[1793:60b] -[NSPathStore2 URLByAppendingPathComponent:]: unrecognized selector sent to instance 0x9da6a10
2014-09-03 22:35:15.753 UBFoodDelivery[1793:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSPathStore2 URLByAppendingPathComponent:]: unrecognized selector sent to instance 0x9da6a10'

可能是因为它找不到sqlite?但是如何添加呢?

【问题讨论】:

【参考方案1】:

您的 applicationDocumentsDirectory 返回一个 NSString 类型。要通过附加路径组件创建 URL,您必须先转换为 NSURL

NSURL *directoryURL = [NSURL fileURLWithPath:[self applicationDocumentsDirectory]];
NSURL *storesDirectory = [directoryURL ...

【讨论】:

NSURL *directoryURL = [NSURL URLWithString:[self applicationDocumentsDirectory]]; -- 这个方法为我返回 nil 是的,fileURLWithPath 帮了我)谢谢!!

以上是关于将 CoreData 添加到现有项目后出错的主要内容,如果未能解决你的问题,请参考以下文章

Swift & Core Data - 将实体添加到现有实体

将 CoreData 添加到现有项目

将 CoreData 添加到现有 iOS 项目 - 无法获取 NSManagedObjectModel

使用 Objective-C 将 CoreData 添加到现有项目中

尝试向 Core Data 添加新记录时出错

在 Core Data (IOS) 中保存数据时出错