数据的持久性存储(二)——CoreData(附Demo)

 CoreData是一款稳定、功能全面的持久性工具。(本文参考iphone开发3所写,比较简要,需详细了解可以参考iphone开发3)

      首先创建一个新的项目CoraData,记得勾选Use Core Data:


        将CoraData 添加到已有的项目中有一定复杂性,因此苹果公司为此选项提供了一些应用程序项目模板,以帮助你完成大部分工作。

        点击Next,继续完成新建工程。完成以后,打开项目的目录:


        你会发现项目中有一个CoreDataTest.xcdatamodeld文件,这是我们的数据模型。CoreData允许可视的方式设计数据模型,而不需要编写代码。单击该文件,你会看到数据模型编辑器:


       点击左下方的Add Entity按钮,添加实体:Line。然后在代码中为这些实体创建托管对象

 

       术语“实体”和“托管对象”可能有点令人混淆,因为两者都表示数据模型对象。术语“实体”表示对对象的描述,而“托管对象”用于在运行时创建的该实体的具体实例。因此,在数据模型编辑器中,你将创建实体,而在代码中,你将创建并检索托管对象。实体和托管对象的差异类似于类与类的实例之间的差异。

 

      然后点击右侧Attribute下方的“+”号,添加属性LineNum,并将类型改为integer 16,添加属性LineText,类型改为string。

      ok,数据模型创建完毕。

 

     然后把界面画好吧,界面如下:


 

       从上图可以看到有四个输入框,一个保存按钮。要做的就是输入字段之后,点击save,将字段保存起来。关闭程序,再次打开,读取持久库中的数据,并填入四个输入框里。

      首先要做的是实现save按钮的实现,实现代码如下(附注释):

 

[plain] view plaincopy  
  1. -(void)save  
  2. {  
  3.      //获取应用程序委托的引用,再用引用获取创建好的托管对象上下文。  
  4.     MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication]delegate];  
  5.     NSManagedObjectContext *context = [delegate managedObjectContext];  
  6.       
  7.     NSError *error;  
  8.     for (int i = 1; i <= 4; i++)  
  9.     {  
  10.         NSString *fieldName = [NSString stringWithFormat:@"line%d",i ];  
  11.         UITextField *theField = [self valueForKey:fieldName];  
  12.           
  13.         //创建提取请求  
  14.         NSFetchRequest *request = [[NSFetchRequest alloc] init];  
  15.           
  16.         //为已创建好的实体利用检索到的上下文创建一个实体描述  
  17.         NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line"  
  18.                                                              inManagedObjectContext:context];  
  19.         //创建好了以后发送给提取请求,以便请求能够知道要查找的实体类型  
  20.         [request setEntity:entityDescription];  
  21.           
  22.         //确定持久库中是否存在与此字段相对应的托管对象,所以穿件一个谓词来确定字段的正确对象:  
  23.         NSPredicate *pred = [NSPredicate predicateWithFormat:@"lineNum == %d",i ];  
  24.         [request setPredicate:pred];  
  25.           
  26.         //由于我们还不知道是从持久库中加载托管对象还是创建新的托管对象,  
  27.         //所以声明一个指向NSManagedObject的指针并将他设置为nil  
  28.         NSManagedObject *theLine = nil;  
  29.           
  30.         //再次在上下文中执行提取请求  
  31.         NSArray *objects = [context executeFetchRequest:request error:&error];  
  32.           
  33.         if (objects == nil)  
  34.         {  
  35.             NSLog(@"There was an error!");  
  36.         }  
  37.           
  38.         //检查示范返回了标准匹配的对象,若果有则加载它,如果没有则创建一个新的托管对象来保存此字段的文本  
  39.         if ([objects count] > 0)  
  40.         {  
  41.             theLine = [objects objectAtIndex:0];  
  42.         }  
  43.         else  
  44.         {  
  45.             theLine = [NSEntityDescription insertNewObjectForEntityForName:@"Line"  
  46.                                                     inManagedObjectContext:context];  
  47.         }  
  48.           
  49.         //使用键值编码来设置行号以及托管对象的文本  
  50.         [theLine setValue:[NSNumber numberWithInt:i] forKey:@"lineNum"];  
  51.         [theLine setValue:theField.text forKey:@"lineText"];  
  52.           
  53.         [request release];  
  54.     }  
  55.     //完成循环之后要通知上下文保存其更改  
  56.     [context save:&error];  
  57. }  


        再看viewDidLoad方法,我们需要确定持久库中是否已经存在数据,如果有则加载数据并使用它填充字段。实现与save方法差不多,实现如下(附注释):

 

 

[plain] view plaincopy  
  1. //获取应用程序委托的引用,再用引用获取创建好的托管对象上下文。  
  2. MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication]delegate];  
  3. NSManagedObjectContext *context = [delegate managedObjectContext];  
  4.   
  5. NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line"  
  6.                                                      inManagedObjectContext:context];;  
  7. NSFetchRequest *request = [[NSFetchRequest alloc] init];  
  8. [request setEntity:entityDescription];  
  9.   
  10. //由于希望检索持久库中所有Line对象,因此没有创建谓词。通过执行没有谓词的请求,上下文将返回库中的每一个Line对象  
  11.   
  12. NSError *error;  
  13.   
  14. NSArray *objects = [context executeFetchRequest:request error:&error];  
  15. //确保返回的是有效数组,如果不是则记录它  
  16. if (objects == nil)  
  17. {  
  18.     NSLog(@"There was an error.");  
  19. }  
  20.   
  21. //然后使用快速枚举遍历已检索托管对象的数组,从中提取LineNum和LineText值,并使用该信息更新用户界面上的文本字段之一  
  22. for (NSManagedObject *oneObject in objects)  
  23. {  
  24.     NSNumber *lineNum = [oneObject valueForKey:@"lineNum"];  
  25.     NSString *lineText = [oneObject valueForKey:@"lineText"];  
  26.       
  27.     NSString *fieldNmae = [NSString stringWithFormat:@"line%d",[lineNum intValue]];  
  28.     UITextField *theField = [self valueForKey:fieldNmae];  
  29.     theField.text = lineText;  
  30. }  
  31.   
  32. [request release];  


       这样就简单的实现了Coredata的存储了。

 

       运行程序,输入一些字段:


        关闭程序,再打开,可以看到字段还在,说明保存成功。

 

        程序demo链接:CoreDataTest Demo

转http://blog.csdn.net/sjx19871225/article/details/8705213

NSPredicate文档中文翻译

http://blog.csdn.net/sjx19871225/article/details/8691720

你可能感兴趣的