0

我在 iOS 中创建了一个单一视图应用程序,它还包含核心数据。我将我的 .xcdatamodel 文件从另一个应用程序移到了我现在正在处理的应用程序中,但我遇到了问题。我所做的是剪切并粘贴上一个应用程序中的代码,并将其放在我的 AppDelegate.h/m 文件中:

@interface DBAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

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

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

@end

和我的 .m 文件:

    @implementation DBAppDelegate

    @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;
//the line below is what is causing an error
        DBViewController *controller = (DBViewController *)navigationController.topViewController;
        controller.managedObjectContext = self.managedObjectContext;


        return YES;
    }

在我的 .m 文件中,我还包含了 Core Data 的样板代码,它也在我之前的应用程序中,但我没有发布。在我的新应用程序中,我正在做的是创建了一个访问层,它还提供了一个 Singleton 实例来访问该层。在这个类中,我进行了 CRUD 操作,并在 .h 文件中声明了以下属性:

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;

目前,我收到以下错误:

“在“DBViewController”类型的对象上找不到属性“managedObjectContext”。我想做的是在我的方法中初始化 managedObjectContext,它允许创建单例实例:

static DB *sharedSingleton = nil;

+ (DB *) sharedInstance {

    if (sharedSingleton == nil) {

        sharedSingleton = [[super alloc] init];

  }

    return sharedSingleton;
}

我究竟做错了什么?我意识到我没有在我的 DBViewController 中声明 managedObjectContext 对象,但是我应该用什么来代替这一行?我认为这与我的 Singleton 课程有关,但老实说,我在这里没有任何线索。

4

1 回答 1

2

您尝试做的通常称为“数据存储”单例,这是一种很好的设计模式。我在我的应用程序中做的是有一个名为 的单例类DataStore,你可以随意调用它,使用类方法:

+ (id)sharedStore{
    static DataStore *sharedStore = nil;
    if (!sharedStore) {
        sharedStore = [[self alloc] init];
    }

    return sharedStore;
}

每当我需要访问数据存储提供的资源时,我都会:

Datastore *ds = [Datastore sharedStore];

为了提供对核心数据的访问,我有一个数据存储方法:

+ (NSManagedObjectContext*)managedObjectContext{
    static NSManagedObjectContext *context = nil;

    if(context){
        return context;
    }

    NSPersistentStoreCoordinator *coordinator = nil;

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

    if (!coordinator) {
        coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objectModel];
    }

    if(!coordinator){
        return nil;
    }

    NSString *storePath = [[self documentsDirectoryPath] stringByAppendingPathComponent:@"datastore.sqlite"];
    NSURL *storeURL = [NSURL URLWithString:storePath];

    NSError *error;

    if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:NULL error:&error])
    {
        NSLog(@"Database error: %@", error);
        // if you make changes to your model and a database already exists in the app
        // you'll get a NSInternalInconsistencyException exception. When the model is updated
        // the databasefile must be removed. Remove the database here because it's easy.
        NSFileManager *fileManager = [NSFileManager defaultManager];
        [fileManager removeItemAtURL:storeURL error:nil];

        //try to add the persistant store one more time. If it still fails then abort
        if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:NULL error:&error])
            return nil;
    }

    context = [[NSManagedObjectContext alloc] init];
    [context setPersistentStoreCoordinator:coordinator];
    [context setUndoManager:nil];

    return context;

}

nil如果NSManagedObjectContext无法创建,则此方法返回。这样你只需要这样做:

NSManagedObjectContext *context = [[DataStore sharedStore] managedObjectContext];

每当您需要使用 Core Data 时。这可以在viewDidLoad.

编辑:

managedObjectContext方法使用以下方法查找文档目录:

+ (NSString *)documentsDirectoryPath
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}
于 2013-09-25T23:10:32.267 回答