Core Data存储自定义类型数据

来源:互联网 发布:mac必备软件 编辑:程序博客网 时间:2024/05/20 21:43

目录:

一、使用CoreData存储基本数据

二、使用CoreData存储自定义类型数据


简单介绍CoreData

  CoreData是iOS编程中使用持久化数据存储的一种方式,我们知道CoreData并不是数据库本身,而是Apple提供的对象持久化技术——Object Persistent technology。CoreData框架为我们的数据变更、管理、对象存储、读取和恢复提供了支持。下面我们来尝试创建一个简单的CoreData Project。


操作

1. 打开x-code,为你的project添加一个新的文件,选择Core Data——>Data Nodel 。如下图:


2. 点击Next,命名后确认就会生成一个 .xcdatamodeld文件


3. 点击该文件就会出现如下界面,我们可以在该界面设置我们需要保存的字段及其类型


点击图片中的左下角 Add Entity按钮即可生成一个新的Entity,此时你就可以在你的Attribute那里添加字段并且设置类型。

我们这次给他添加了name与year,这两个是我们后面需要保存的值。


4. 点击editor,选择create NSManagedObject Subclass,你会发现他自动帮我们生成了对应的文件,方便我们后期对这些字段进行操作。




打开AppDelegate.h文件,你会发现这里面多了三个属性:

<span style="font-size:14px;">#import <UIKit/UIKit.h>#import <CoreData/CoreData.h>@class ViewController;@interface AppDelegate : UIResponder <UIApplicationDelegate>@property (strong, nonatomic) UIWindow *window;@property (strong,nonatomic)ViewController *viewController;//上下文对象@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;//数据模型对象@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;//持久性存储区@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;- (void)saveContext;- (NSURL *)applicationDocumentsDirectory;//初始化CoreData使用的数据库-(NSPersistentStoreCoordinator *)persistentStoreCoordinator;//managedObjectModel的初始化赋值方法-(NSManagedObjectModel *)managedObjectModel;//managedObjectContext的初始化赋值方法-(NSManagedObjectContext *)managedObjectContext;@end</span>
这是x-code为我们生成好了的模板,我们在需要保存数据的地方调用他们进行操作即可。


下面我们开始操作:

viewController.h

<span style="font-size:14px;">#import <UIKit/UIKit.h>#import "AppDelegate.h"@interface ViewController : UIViewController@property (strong,nonatomic)AppDelegate *myDelegate;@property (strong,nonatomic)NSMutableArray *entries_array;@end</span>
AppDelegate *mydelegate可以让我们调用AppDelegate中新增的三个属性


ViewController.m

<span style="font-size:14px;">#import "ViewController.h"#import "Entity.h"@interface ViewController ()@end@implementation ViewController@synthesize myDelegate ;@synthesize entries_array ;- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    //获取当前应用的委托(UIApplication sharedApplication为整个应用的上下文)    self.myDelegate = [[UIApplication sharedApplication]delegate];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}-(void)saveData{    Entity *entity = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:self.myDelegate.managedObjectContext];    NSNumber *number = [[NSNumber alloc]initWithInt:3];    [entity setName:@"Lion"];    [entity setYear:number];    NSError *error;    if(![NSEntityDescription entityForName:@"Entity" inManagedObjectContext:self.myDelegate.managedObjectContext]){        NSLog(@"Error:%@,%@",error,[error userInfo]);    }else{        NSLog(@"Save Success!");    }}-(void)queryData{    //设置请求实体    NSFetchRequest *request = [[NSFetchRequest alloc]init];    [request setEntity:[NSEntityDescription entityForName:@"Entity" inManagedObjectContext:self.myDelegate.managedObjectContext]];    //指定对结果的排序    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"year" ascending:NO];    NSArray *sortArray  = [[NSArray alloc]initWithObjects:sortDescriptor, nil];    [request setSortDescriptors:sortArray];        //执行请求    NSError *error = nil;    NSMutableArray *fetchResultArray = [[self.myDelegate.managedObjectContext executeFetchRequest:request error:&error]mutableCopy];        //判断,如果获取到的数据为空:    if(fetchResultArray == nil){        NSLog(@"Error:%@,%@",error,[error userInfo]);    }        self.entries_array = fetchResultArray;    NSLog(@"The count of the Data:%lu",[self.entries_array count]);    for(Entity *entity in self.entries_array){        NSLog(@"leg:  %@\nname:  %@\n",entity.name,entity.year);    }}</span>


二、使用CoreData存储自定义类型数据

  当系统提供给我们的类型不能达到我们的使用要求时怎么办?比如我们想要在CoreData存储一个自定义类的对象可不可以呢?答案是可以的。

这时候你就会注意到在选择属性的时候会发现最后一行有一个Transformable类型,下面我们就会用上他。
我们建立一个简单的类叫做“Cat”,设置两个属性,一个是leg(int),一个name(NSString)(具体过程省略)


注意右边Name的填值。

现在根据我们的模型来生成数据模型,并且创建用于转换Cat的类,继承自NSValueTransform,注意这个转换类的名字要跟上面Name的名字一致


打开Cattransformer.m 要实现4个必须实现的方法:

<span style="font-size:14px;">//允许转换+(BOOL)allowsReverseTransformation{    return YES;}//转换成什么类型+(Class)transformedValueClass{    return [NSData class];}//返回转换后的对象-(id)transformedValue:(id)value{    Cat *cat = (Cat *)value;    //将对象转换成NSData    NSData *dataFromCat = [[NSData alloc]initWithBytes:(__bridge const void *)(cat) length:sizeof(cat)];    return dataFromCat;}//重新生成源对象-(id)reverseTransformedValue:(id)value{    NSData *data = (NSData *)value;    Cat *cat = [[Cat alloc]init];    [data getBytes:(__bridge void *)(cat) length:sizeof(cat)];    return cat;}</span>
到这里其实已经很明白了,整个过程与上面的存储并无大异,之时我们使用了NSData作为中间转换的值。


打开ViewController.m文件,在原来saveData方法里面插入:

<span style="font-size:14px;">Cat *cat = [[Cat alloc]init];    cat.leg = 4;    cat.name = @"Holle";    [entity setCat:cat];</span>
就可以实现存储了。

  至此,简单的Demo就算是完成了,需要注意的是在我们编译成功之后想要更改Entity中的字段,除了需要更改.xcdatamodeld文件以外,你还需要手动更改Entity.h与Entity.m文件,而不能像之前那样让他们自动生成,此时点击运行还是会发生错误,这时候需要注意,一是你的命名是否错误,其次可能是之前的旧的数据库文件现在需要存储的数据无法对应,你需要将模拟器上的工程删除然后重新运行即可。

0 0