上篇文章我們已經(jīng)把core Data的創(chuàng)建方式以及過(guò)程介紹完了,這篇文章主要內(nèi)容是介紹一個(gè)core Data的管理類(lèi), 我們對(duì)其進(jìn)行封裝, 用的時(shí)候直接可以對(duì)數(shù)據(jù)進(jìn)行增刪改查的操作, 用起來(lái)十分方便.
core Data主要的幾個(gè)類(lèi):
管理對(duì)象模型, 一個(gè)模型關(guān)聯(lián)著一個(gè)模型文件(. xcdatamodeld),儲(chǔ)存著數(shù)據(jù)庫(kù)的數(shù)據(jù)結(jié)構(gòu)
NSManagedObjectModel
持久化存儲(chǔ)調(diào)度器, 負(fù)責(zé)協(xié)調(diào)存儲(chǔ)區(qū)和上下文之間的關(guān)系
NSPersistentStoreCoordinator
管理對(duì)象上下文
NSManagedObjectContext
首先要把這幾個(gè)對(duì)象初始化, 這里我們用懶加載的方式:
管理對(duì)象模型
- (NSManagedObjectModel *)managedObjectModel{
if (!_managedObjectModel) {
//URL為coreDataTest.xcdatamodeld(你本地的xcdatamodeld名)的
//注意:拓展名應(yīng)該是momd,而不是xcdatamodeld
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"coreDataTest" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
}
return _managedObjectModel;
}
持久化存儲(chǔ)調(diào)度器
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (!_persistentStoreCoordinator) {
//創(chuàng)建coodinator需要傳入的managedObjectModel
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
//指定本地的SQLite數(shù)據(jù)庫(kù)文件
NSURL *sqliteURL = [[self documentDirectoryURL] URLByAppendingPathComponent:@"coreDataTest.sqlite"];
NSLog(@"本地SQLite數(shù)據(jù)庫(kù)文件路徑=%@", sqliteURL);
NSError *error;
//為 persistentStoreCoordinator 制定本地存儲(chǔ)的類(lèi)型, 這里制定的是SQLite
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqliteURL options:nil error:&error];
if (error) {
NSLog(@"failed to create persistentStoreCoordinator__%@", error.localizedDescription);
}
}
return _persistentStoreCoordinator;
}
管理對(duì)象上下文
- (NSManagedObjectContext *)context{
if (!_context) {
// 指定context的并發(fā)類(lèi)型:NSMainQueueConcurrencyType 或 NSPrivateQueueConcurrencyType
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_context.persistentStoreCoordinator = self.persistentStoreCoordinator;
}
return _context;
}
下面這幾個(gè)是我們初始化以上幾個(gè)對(duì)象時(shí)用的幾個(gè)方法:
#pragma mark --創(chuàng)建document目錄
- (nullable NSURL *)documentDirectoryURL
{
return [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
}
#pragma mark --讀取數(shù)據(jù)請(qǐng)求
- (NSFetchRequest *)fetchRequest:(NSString *)entityName predicate:(NSString *)predicateString
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:_context]];
if (predicateString != nil) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
[request setPredicate:predicate];
}
return request;
}
#pragma mark --allAttributes
- (NSMutableArray *)ClassAttributes:(id)classModel
{
NSMutableArray *array = [NSMutableArray array];
NSString *className = Class_Name(classModel);
const char *cClassName = [className UTF8String];
id classM = objc_getClass(cClassName);
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(classM, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
NSString *attributeName = [NSString stringWithUTF8String:property_getName(property)];
[array addObject:attributeName];
}
return array;
}
#pragma mark --保存數(shù)據(jù)到持久層
- (BOOL)saveContext
{
NSManagedObjectContext *context = [self context];
if (context) {
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
abort();
return NO;
}
}
return YES;
}
這些做完了我們就可以對(duì)數(shù)據(jù)進(jìn)行增刪改查的操作了, 具體的實(shí)現(xiàn)如下:
#pragma mark --數(shù)據(jù)的增刪改查
/**
插入數(shù)據(jù)
*/
- (BOOL)insertModel:(id)model
{
NSManagedObject *manager = [NSEntityDescription insertNewObjectForEntityForName:Class_Name(model) inManagedObjectContext:_context];
for (NSString *propertyName in [self ClassAttributes:model]) {
[manager setValue:[model valueForKey:propertyName] forKey:propertyName];
}
BOOL result = [self saveContext];
if (result) {
NSLog(@"插入數(shù)據(jù)成功__%@", model);
}else{
NSLog(@"插入數(shù)據(jù)失敗");
}
return result;
}
/**
刪除數(shù)據(jù)
*/
- (BOOL)removeModel:(id)model predicateString:(NSString *)predicateString
{
NSError *error = nil;
NSArray *listArray = [_context executeFetchRequest:[self fetchRequest:Class_Name(model) predicate:predicateString] error:&error];
if (listArray.count > 0) {
for (NSManagedObject *manager in listArray) {
[_context deleteObject:manager];
}
NSLog(@"刪除成功");
}else{
NSLog(@"數(shù)據(jù)為空,無(wú)法繼續(xù)刪除");
}
return [self saveContext];
}
/**
修改數(shù)據(jù)
*/
- (BOOL)changeModel:(id)model predicateString:(NSString *)predicateString
{
NSError *error = nil;
NSArray *listArray = [_context executeFetchRequest:[self fetchRequest:Class_Name(model) predicate:predicateString] error:&error];
if (listArray.count > 0) {
for (NSManagedObject *manager in listArray) {
for (NSString *propertyName in [self ClassAttributes:model]) {
[manager setValue:[model valueForKey:propertyName] forKey:propertyName];
}
NSLog(@"修改成功__%@", manager);
}
}
return [self saveContext];
}
/**
查詢(xún)數(shù)據(jù)
*/
- (NSMutableArray *)findByModel:(id)model predicateString:(NSString *)predicateString
{
NSError *error = nil;
NSArray *listArray = [_context executeFetchRequest:[self fetchRequest:Class_Name(model) predicate:predicateString] error:&error];
NSMutableArray *resultArray = [[NSMutableArray alloc] initWithArray:listArray];
return resultArray;
}
這樣我們對(duì)Core Data的封裝就完成了,具體的使用方法如下:
我們要在自己的控制器里面調(diào)用上述的幾個(gè)接口, 對(duì)數(shù)據(jù)進(jìn)行增刪改查,
首先要引入模型類(lèi)和管理類(lèi)
#import "Person+CoreDataClass.h"
#import "LCCoreDataManager.h"
然后把我們剛才寫(xiě)好的管理類(lèi)以及模型文件進(jìn)行初始化
LCCoreDataManager *coreDataManager = [LCCoreDataManager shareInstanceWithStoreName:@"Person"];
Person *personModel = [[Person alloc] initWithEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:coreDataManager.context] insertIntoManagedObjectContext:nil];
接下來(lái)就可以進(jìn)行相應(yīng)的增刪改查操作了, 這些方法需要放在對(duì)應(yīng)的調(diào)用方法里面:
/**
插入數(shù)據(jù)
*/
- (void)clickInsertBtn
{
LCCoreDataManager *coreDataManager = [LCCoreDataManager shareInstanceWithStoreName:@"Person"];
Person *personModel = [[Person alloc] initWithEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:coreDataManager.context] insertIntoManagedObjectContext:nil];
personModel.name = @"kobe";
personModel.age = 37;
personModel.height = 198;
[coreDataManager insertModel:personModel];
}
/**
刪除數(shù)據(jù)
*/
- (void)clickDeleteBtn
{
LCCoreDataManager *coreDataManager = [LCCoreDataManager shareInstanceWithStoreName:@"Person"];
Person *personModel = [[Person alloc] initWithEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:coreDataManager.context] insertIntoManagedObjectContext:nil];
//predicateString--需要?jiǎng)h除的數(shù)據(jù)的條件
[coreDataManager removeModel:personModel predicateString:@"age = 40"];
}
/**
修改數(shù)據(jù)
*/
- (void)clickChangeBtn
{
LCCoreDataManager *coreDataManager = [LCCoreDataManager shareInstanceWithStoreName:@"Person"];
Person *personModel = [[Person alloc] initWithEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:coreDataManager.context] insertIntoManagedObjectContext:nil];
//要修改的數(shù)據(jù)
personModel.name = @"jordon";
personModel.height = 199;
personModel.age = 40;
//需要被修改的數(shù)據(jù) (所有age = 37的進(jìn)行修改)
[coreDataManager changeModel:personModel predicateString:@"age = 37"];
}
/**
查詢(xún)數(shù)據(jù)
*/
- (void)clickSearchBtn
{
LCCoreDataManager *coreDataManager = [LCCoreDataManager shareInstanceWithStoreName:@"Person"];
Person *personModel = [[Person alloc] initWithEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:coreDataManager.context] insertIntoManagedObjectContext:nil];
//要查詢(xún)數(shù)據(jù)的條件
NSMutableArray *PersonArr = [coreDataManager findByModel:personModel predicateString:@"age = 37"];
NSLog(@"%ld", PersonArr.count);
for (Person *personM in PersonArr) {
NSLog(@"%@=%d=%d", personM.name,personM.age, personM.height);
}
}
以上就是所有的關(guān)于Core Data的封裝以及具體調(diào)用的介紹了,這里只是針對(duì)簡(jiǎn)單的增刪改查進(jìn)行操作, 如需其他需求, 需要根據(jù)自己的需要自行進(jìn)行修改. 下面附上demo的地址, 如還有不懂的地方, 可以看demo上的內(nèi)容.