群里有小伙伴向我反应,说用到CoreData的时候会一头雾水,不知如何使用,感觉涉及到的类和对象好多,根本记不过来,只能用第三方的来弄,自己写却不知道如何下笔
其实最初我也是这样,但是一步一步摸索,就把自己对它的理解总结到这里,希望可以对读者有一点帮助
首先我们要了解以下5个对象分别是干嘛的,以及如何来记住它们
1.NSManagedObjectContext:按字面翻译为被管理的对象上下文,既然是上下文,那么一定起到了桥接的作用,它桥接的就是某个对象与数据库之间的关系,那么接下来我们要找到它桥接的数据库
2.NSPersistentStoreCoordinator:按字面翻译为固执的存储协调器,既然涉及到存储器,那么它一定是类似数据库的对象,而contenxt恰好有一个属性就是它,数据库我们找到了,还差与它相连接的对象,我们继续找context的属性,发现没有类似对象的属性,但有一个方法叫insertObject:(NSManagedObject *)object;从这个方法,我们可以联想到这个对象一定是NSManagedObject类型的,我们再去看看存储器类里面是否有类似的属性,进去以后发现有一个NSManagedObjectModel的属性,还有一个带其参数的初始化方法,那一定是它了
3.NSManagedObjectModel:按字面翻译为被管理的对象模型,可想而知,它应该是数据库里面的对象模型,我们来看看它里面的属性,有entities,可想而知它是实体的集合,那么我们再来看之前insertObject方法里面的NSManagedObject对象
4.NSManagedObject:按字面翻译为被管理的对象,在里面我们会找到一个entity的属性,跟我们之前猜测的一样,它才是与实体有一对一的关系,而Model则是一对多,再看它的初始化方法initWithEntity:(NSEntityDescription *)entity里面有一个NSEntityDescription的参数,我们再来看看它是什么
5.NSEntityDescription:按字面翻译为实体描述,终于到了CoreData中的最重要的元素,那就是实体,没错,实体就是数据库中的表属性,而这个实体我们在项目中应该怎样获得呢?接下来我们就用Xcode自带CoreData文件来创建实体
如图所示:
点击Add Entity按钮
然后在右方属性处改变它的名字
接下来添加属性和关联关系,这里我们创建两个实体
如图所示:
我们已经创建好对应的实体,并且加上了对应的属性,还有相应的关联对象,这里面的关联对象其实就是在表里存了一个对象属性,而这个对象就是我们已经创建好的实体,它适用延迟加载机制,所以再用的时候才会对它进行加载
下面我们来生成这两个实体
这里面的关联对象,它是自动识别的,由于之前的关联实体对象的名字我达成了newtest而不是newTest,所以导致系统并没有找到对应的关联对象,所以出现了这个对象是基类类型NSManagedObject,而不是NewTest类型,这也是平常要养成驼峰代码规范的习惯
OK,这样我们的实体就已经生成了哦,在工程的左侧对应栏里哦
接下来我们先创建context
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] init];
然后我们创建PersistentStoreCoordinator,会发现它需要一个NSManagedObjectModel参数,于是我们先创建一个NSManagedObjectModel对象
//从api中可以看到,nil其实就是指main Bundle,而main Bundle就是指当前的Group文件夹,所以我们通过Group文件夹来获取managedObject的集合 NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
接下来为这个PersistentStoreCoordinator创建一个对象存储路径,跟SQLite操作很像哦
//创建好存储器以后我们应该找到方法来设置它的存储路径,根据API我们查到了如下的添加存储数据路径的方法,返回值是一个NSPersistentStore* //根据API,如下图所示,我们第一个参数使用SQLite类型来存储,但我们还需要创建一个路径来保证它的url参数 if (0 == persistentStoreCoordinator.persistentStores.count) { NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"test.data"]]; NSError *error = nil; NSPersistentStore *store = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]; if (!store) { NSLog(@"数据库出现错误"); } }
然后将PersistentStoreCoordinator对象指定给context
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator;
这时候context就已经配置好了,我们来创建一个实体,并且对其做相应的修改
NSEntityDescription *testEntity; if ([NSEntityDescription entityForName:@"Test" inManagedObjectContext:managedObjectContext]) { testEntity = [NSEntityDescription entityForName:@"Test" inManagedObjectContext:managedObjectContext]; } else { testEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:managedObjectContext]; }
那么我们如何修改实体的值并做保存呢
//entity是实体,不可变的实体,将它改变成managedObject以后就可以对它进行修改,变成可修改的实体,但需要用到KVC,也就是setValue:forKey: //并且直接实现插入数据库的操作 NSManagedObject *testManagedObject = [[NSManagedObject alloc] initWithEntity:testEntity insertIntoManagedObjectContext:managedObjectContext]; //接下来我们为Test实体赋值一些属性 [testManagedObject setValue:@"swh" forKey:@"name"]; [testManagedObject setValue:[NSNumber numberWithFloat:30] forKey:@"num"]; //再做查询 NSArray *array = [managedObjectContext executeFetchRequest:[NSFetchRequest fetchRequestWithEntityName:@"Test"] error:nil];
在上面的编码过程中,我们会发现,Entity是不可变的实体,不能对它进行修改,而将它改变成NSManagedObject对象以后,就可以对这个对象进行set value for key的修改,可知NSManagedObject对象应该是一个可变的实体
其实当我们创建好数据库存储路径以后,运行代码后进入文档目录,你可以看到如下图所示哦
CoreData是不是很简单很好用呢,其实只要稍微调研一下各个属性,其实用起来还蛮方便的,就是代码量要多一点,是个蛋疼的事情
今天就介绍这么多吧,只是CoreData的简单使用哦
在这里为大家推荐一款非常常用的CoreData三方类库:MagicalRecord
用起来真的很方便哦,但是我们一定要了解CoreData中的那些属性与方法哦