在
上一篇中简单介绍了Core Data Stack,自上而下地对Core Data应用结构有个基本的认识,不过都是理论上的。这里就以上一篇的理论构建起一个可运行的Demo,执行一些简单的增删改查操作。
(图片来自Apple)
首先,我们需要建立如上图的栈结构。因此,在ViewController里添加3个属性:
- @interface ViewController : UIViewController
- @property (nonatomic, retain) NSManagedObjectModel *managedObjectModel;
- @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
- @property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- @end
根据前文讨论的顺序,我们首先创建managedObjectModel(在那之前需要引入CoreData Framework):
- - (NSManagedObjectModel *)managedObjectModel
- {
- if (nil != _managedObjectModel) {
- return _managedObjectModel;
- }
- _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
- return _managedObjectModel;
- }
接着创建NSManagedObject的生存环境 —— NSManagedObjectContext:
- - (NSManagedObjectContext *)managedObjectContext
- {
- if (nil != _managedObjectContext) {
- return _managedObjectContext;
- }
- _managedObjectContext = [[NSManagedObjectContext alloc] init];
- return _managedObjectContext;
- }
由于Demo会将数据存储到本地文件,所以还需要NSPersistentStoreCoordinator和NSManagedObjectContext配合。
下面是
创建Core Data栈结构的完整代码:
- #pragma mark -
- #pragma mark - Core Data Stack
- - (NSManagedObjectModel *)managedObjectModel
- {
- if (nil != _managedObjectModel) {
- return _managedObjectModel;
- }
- _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
- return _managedObjectModel;
- }
- - (NSManagedObjectContext *)managedObjectContext
- {
- if (nil != _managedObjectContext) {
- return _managedObjectContext;
- }
- _managedObjectContext = [[NSManagedObjectContext alloc] init];
- if (self.persistentStoreCoordinator) {
- [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
- }
- return _managedObjectContext;
- }
- - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
- {
- if (nil != _persistentStoreCoordinator) {
- return _persistentStoreCoordinator;
- }
- NSString *storeType = NSSQLiteStoreType;
- NSString *storeName = @"cdNBA.sqlite";
- NSError *error = NULL;
- NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:storeName]];
- _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
- if (![_persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nilURL:storeURL options:nil error:&error]) {
- NSLog(@"Error : %@\n", [error localizedDescription]);
- NSAssert1(YES, @"Failed to create store %@ with NSSQLiteStoreType", [storeURL path]);
- }
- return _persistentStoreCoordinator;
- }
- #pragma mark -
- #pragma mark Application's Documents Directory
- - (NSString *)applicationDocumentsDirectory
- {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
- return basePath;
- }
在搭建完基础的Core Data栈结构后,就可以写一些简单的CURD代码了:
- #pragma mark -
- #pragma mark - CURD Operations
- - (BOOL)createTeamWithName:(NSString *)teamName city:(NSString *)teamCity
- {
- if (!teamName || !teamCity) {
- return NO;
- }
- NSManagedObject *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
- [teamObject setValue:teamName forKey:@"name"];
- [teamObject setValue:teamCity forKey:@"city"];
- return YES;
- }
- - (NSArray *)fetchTeamList
- {
- NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
- [fetchRequest setEntity:[NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext]];
- NSError *error = NULL;
- NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
- if (error) {
- NSLog(@"Error : %@\n", [error localizedDescription]);
- }
- [fetchRequest release], fetchRequest = nil;
- return array;
- }
我们可以把读写的代码放到viewDidLoad函数中:
- - (void)viewDidLoad
- {
- [superviewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- [self createTeamWithName:@"Heat"city:@"Miami"];
- [self createTeamWithName:@"Lakers"city:@"LA"];
- [self saveContext];
- NSArray *teamArray = [self fetchTeamList];
- if (teamArray) {
- for (NSManagedObject *teamObject in teamArray) {
- NSString *teamName = [teamObject valueForKey:@"name"];
- NSString *teamCity = [teamObject valueForKey:@"city"];
- NSLog(@"Team info : %@, %@\n", teamName, teamCity);
- }
- }
- }
由于在context中创建的对象只是存在于内存中,所以我们还需要显式地把数据保存到sqlite文件里:
- #pragma mark -
- #pragma mark - Save Context
- - (void)saveContext
- {
- NSError *error = NULL;
- NSManagedObjectContext *moc = self.managedObjectContext;
- if (moc && [moc hasChanges] && ![moc save:&error]) {
- NSLog(@"Error %@, %@", error, [error localizedDescription]);
- abort();
- }
- }
最后,就是跑一下Demo,检验一下结果。
执行过一次程序后,我们可以搜索下cdNBA.sqlite文件,然后查看里面的数据:
同时,控制台也输出了数据:
- 2013-01-16 14:32:52.638 cdNBA[4717:c07] Team info : Heat, Miami
- 2013-01-16 14:32:52.639 cdNBA[4717:c07] Team info : Lakers, LA