创建工程的时候,如果是基于windows的,就有选择支持coreData,其它的project temple则没有支持coreData选项。如果项目进行到一半,需要加如coreData的支持如何办呢? 我们创建基于windows的工程时,会看到在appdelegate里加入了一些代码,这些代码就是与coreData相关的,我们把它移到我们自己的工程当中,就可以支持coreData了。下面介绍一下具体步骤。
第一步:加入coredata.framework
第二步:在prefix.pch中加入#import <CoreData/CoreData.h>
第三步:
在.h中加入变量声明
NSManagedObjectContext *managedObjectContext_; NSManagedObjectModel *managedObjectModel_; NSPersistentStoreCoordinator *persistentStoreCoordinator_;
在.h中加入方法声明与属性声明
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory; - (void)saveContext;
在.m中加方法实现
#pragma mark - #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) { return managedObjectModel_; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"pocData" withExtension:@"momd"]; managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; //managedObjectModel_ = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; 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:@"pocData.sqlite"]; DLog(@"db: %@",[storeURL absoluteURL]); NSError *error = nil; persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self 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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 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: [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 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_; } #pragma mark - #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]; } #pragma mark -- #pragma mark function - (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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. */ NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } - (void)dealloc { [super dealloc]; [managedObjectContext_ release]; [managedObjectModel_ release]; [persistentStoreCoordinator_ release]; }
第四步:加入.xcdatamodel文件
File->New File->Resource->Data Model
第五步: 创建coreData bundle
这是创建bundle了的样子
这是没有bundle的样子
选中第四步创建的文件,然后选择主菜单中的Design->Data Model->Add Model Version, 这一步必须进行,不然要crash.
具体原困就是,如果没有coreData bundle,就无法编译成momd文件,那么在- (NSManagedObjectModel *)managedObjectModel 这个方法中就无法找到momd文件,initWithContentsOfURL:modelURL 这个方法就crash。
参考:http://stackoverflow.com/questions/4518000/how-to-create-the-magic-xcdatamodeld-folder-package/4518137#4518137
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/XcodeCoreDataTools/Articles/xcdCompilerFlags.html#//apple_ref/doc/uid/TP40006871-SW1
完成上面五步你就可以用coreData了。
补充:
- (NSManagedObjectModel *)managedObjectModel 这个方法当中我注掉了一行, 它与它上面两行功能一样。 如果把这个方法改为如下的话就不需要第五步操作,也不会crash.
- (NSManagedObjectModel *)managedObjectModel { if (managedObjectModel_ != nil) { return managedObjectModel_; } // NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"pocData" withExtension:@"momd"]; //managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; managedObjectModel_ = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; return managedObjectModel_; }