CoreData实例分析学习(1)

2009年12月15日 23:00

 Core Data是个好东西,在数据储存操作上速度快,容易操作,是一种类似关系数据库的东西。但是有些不那么好学,那到底Core Data是怎么操作的呢?怎么用呢?怎么来编程呢?我们一起来学习吧,接下来使用苹果提供的实例程序Locations来作分析:

 

>程序介绍:

右侧是改程序的截图,基本上来说就是通过使用Core Location来得到当时的位置,然后在点击“+”的时候记录下当时的经纬度。通过UITableViewController的功能来添加,编辑,删除等功能。整体程序使用Core Data来储存数据,实体(Entity)为一个位置,包括以下参数:1,时间(收集数据的时间)2,纬度,3,经度

首先我们看看该程序的AppDelegate.h

  1. @interface LocationsAppDelegate : NSObject  {
  2.     UIWindow *window;
  3.     UINavigationController *navigationController; //导航栏
  4.  
  5.     //以下定义了Core Data的三个决定性组建,等后面m文件里面再多介绍
  6.     NSPersistentStoreCoordinator *persistentStoreCoordinator;
  7.     NSManagedObjectModel *managedObjectModel;
  8.     NSManagedObjectContext *managedObjectContext;
  9. }
  10.  
  11. @property (nonatomic, retain) IBOutlet UIWindow *window;
  12. @property (nonatomic, retain) UINavigationController *navigationController;
  13.  
  14. - (IBAction)saveAction:sender; //这个没找到作用...根本就没用到IB
  15.  
  16. //还记得吧,nonatomic是因为这个程序是单线程
  17. @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
  18. @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
  19. @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator
  20.                               *persistentStoreCoordinator;
  21. @property (nonatomic, readonly) NSString *applicationDocumentsDirectory;
  22. //程序文档目录是主要为了给NSPersistentStoreCoordinator找个存SQLite文件的地方
  23. @end

  

从上面的我们能看出来,该程序是通过一个根Core Data数据管理来管理整个程序的CoreData数据的,接下来看m文件也会对此作更多的理解。

 

  1. #import "LocationsAppDelegate.h"
  2. #import "RootViewController.h" //该程序使用了一个根视图控制器,所以导入了这个类
  3. @implementation LocationsAppDelegate
  4. @synthesize window;
  5. @synthesize navigationController;
  6.  
  7. - (void)applicationDidFinishLaunching:(UIApplication *)application {
  8.         //初始化根视图控制器,它是一个列表视图控制器
  9.         RootViewController *rootViewController = [[RootViewController alloc]
  10.              initWithStyle:UITableViewStylePlain];
  11.  
  12.         //通过下面的自定义getter得到CoreData的“被管理对象内容器”
  13.         NSManagedObjectContext *context = [self managedObjectContext];
  14.         if (!context) {
  15.                 // 如果getter出错,在这里来排错
  16.         }
  17.         rootViewController.managedObjectContext = context;
  18.         //rootViewController有一个本地“被管理对象内容器”,在这里赋值过去
  19.  
  20.         UINavigationController *aNavigationController = [[UINavigationController alloc]
  21.              initWithRootViewController:rootViewController];
  22.         self.navigationController = aNavigationController;
  23.         //初始化导航栏,根视图为rootViewController,并指定该导航栏为程序导航栏
  24.         [window addSubview:[navigationController view]];
  25.         [window makeKeyAndVisible];
  26.  
  27.         //由于导航栏retain了根视图,所以在这里可以release掉它了
  28.         [rootViewController release];
  29.         //由于self已经retain了导航栏,所以导航栏可以release
  30.         [aNavigationController release];
  31. }
  32.  
  33. //applicationWillTerminate: 在程序结束前,Core Data会保存任何对其的更改
  34. - (void)applicationWillTerminate:(UIApplication *)application {
  35.  
  36.     NSError *error;
  37.     if (managedObjectContext != nil) {
  38.         if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
  39.                         // Handle the error.
  40.         }
  41.     }
  42. }
  43.  
  44. //在得到点击事件后,保存更改
  45. - (IBAction)saveAction:(id)sender {
  46.  
  47.     NSError *error;
  48.     if (![[self managedObjectContext] save:&error]) {
  49.                 // Handle error
  50.     }
  51. }
  52.  
  53. //自定义的managedObjectContext的getter, 它其实是真正在使用的时候的被操作对象
  54. - (NSManagedObjectContext *) managedObjectContext {
  55.  
  56.     //如果已经有这个对象,就直接返回,否则继续
  57.     if (managedObjectContext != nil) {
  58.         return managedObjectContext;
  59.     }
  60.  
  61.     NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
  62.     if (coordinator != nil) {
  63.         managedObjectContext = [[NSManagedObjectContext alloc] init];
  64.         [managedObjectContext setPersistentStoreCoordinator: coordinator];
  65.        //这里可以看到,“内容管理器”和“数据一致性存储器”的关系,
  66.        //managedObjectContext需要得到这个“数据一致性存储器”
  67.     }
  68.     return managedObjectContext;
  69. }
  70.  
  71. //自定义的CoreData数据模板的getter,数据模板其实就是一个描述实体与实体的关系
  72. //,类似于关系型数据库的关系描述文件
  73. - (NSManagedObjectModel *)managedObjectModel {
  74.  
  75.     if (managedObjectModel != nil) {
  76.         return managedObjectModel;
  77.     }
  78.     managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
  79.     //从本地所有xcdatamodel文件得到这个CoreData数据模板
  80.     return managedObjectModel;
  81. }
  82.  
  83. //自定义“数据一致性存储器” persistentStoreCoordinator的getter
  84. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
  85.  
  86.     if (persistentStoreCoordinator != nil) {
  87.         return persistentStoreCoordinator;
  88.     }
  89.  
  90.     //定义一个本地地址到NSURL,用来存储那个SQLite文件
  91.     NSURL *storeUrl = [NSURL fileURLWithPath:
  92.             [[self applicationDocumentsDirectory]
  93.                             stringByAppendingPathComponent: @"Locations.sqlite"]];
  94.  
  95.         NSError *error;
  96.     persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
  97.             initWithManagedObjectModel: [self managedObjectModel]];
  98.     //从这里可以看出,其实persistentStoreCoordinator需要的不过是一个
  99.     //存储数据的位置,它是负责管理CoreData如何储存数据的
  100.     if (![persistentStoreCoordinator
  101.         addPersistentStoreWithType:NSSQLiteStoreType
  102.         configuration:nil
  103.         URL:storeUrl
  104.         options:nil
  105.         error:&error]) {
  106.         // Handle the error.
  107.     }   
  108.  
  109.     return persistentStoreCoordinator;
  110. }
  111.  
  112. //返回该程序的档案目录,用来简单使用
  113. - (NSString *)applicationDocumentsDirectory {
  114.  
  115.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
  116.                             NSUserDomainMask, YES);
  117.     NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
  118.     return basePath;
  119.     //我原来的帖子中介绍过,方法其实是一模一样的
  120. }
  121.  
  122. - (void)dealloc {
  123.  
  124.     //释放内存
  125.     [managedObjectContext release];
  126.     [managedObjectModel release];
  127.     [persistentStoreCoordinator release];
  128.  
  129.         [navigationController release];
  130.         [window release];
  131.         [super dealloc];
  132. }
  133. @end

 

从上面的程序主代理文件可以看出,CoreData的简单使用不过是通过三个组建。

NSManagedObjectModel来描述实体与实体的关系,也就是类似于表和表的关系。
NSManagedObjectContext来得到被储存内容的文件管理器,对数据作直接操作
NSPersistentStoreCoordinator来管理数据的储存位置,储存方法(SQLite)

你对Core Data理解更多了么?

 

补一下“实体”的概念,实体也就是Entity,在打开xcdatamodel文件的时候,我们可以看到

屏幕快照 2009-08-26 下午05.08.29

在这里,这个实体叫“Event”,而实体的参数有“创建日期”,“纬度”,“经度”。也就是说,其实这个实体被使用后,我们可以这样理解,实体就是表名,而参数就是列名,然后整个实体就是一张表。当这个Model描述多个实体的关系的时候,就像是一个关系型数据库一样,虽然苹果说“不是!”