为了方便使用CoreData 封装了几个扩展类,使用方法和类文件如下:
//首先需要在AppDelegate中的 application:didFinishLaunchingWithOptions:中调用:[CoreDataUtil launch]; //使用方法:model中有2个表User、Bank;其中User表中的RelationShip:user对应多条Bank记录 /* 清空User表 */ [NSManagedObject cleanTable:NSStringFromClass([User class])]; /* 像User表插入一条数据 */ NSDictionary *userDic = @{@"name":@"jizhi",@"age":@(23),@"bank":@[@{@"account":@"111111"},@{@"account":@"222222"}]}; User *user = (User *)[NSManagedObject addObject_sync:userDic toTable:NSStringFromClass([User class])]; NSLog(@"user ----> %@",user); /* 修改刚刚插入的数据 */ userDic = @{@"name":@"jizhi",@"age":@(23),@"bank":@[@{@"account":@"444444"},@{@"account":@"555555"},@{@"account":@"666666"}]}; user = (User *)[NSManagedObject updateObject_sync:user params:userDic]; NSLog(@"user ----> %@",user); /* 查询User表中的所有记录 */ NSArray *array = [NSManagedObject getTable_sync:NSStringFromClass([User class]) predicate:nil]; NSLog(@"array ----> %@",[array firstObject]);
NSManagedObject+Explain 为数据库的几个基本操作:增删改查 ,所有操作在同一个线程中进行;
所有的数据库操作都应调用 NSManagedObject+Explain 中的方法,一般不去改变这个扩展类;
如果还需要自定义方法,可以在 NSManagedObject+Magic 这个扩展类中添加。
3个类文件分别如下:
// CoreDataUtil.h
// // CoreDataUtil.h // CoreDataUtil // // Created by marujun on 14-1-13. // Copyright (c) 2014年 jizhi. All rights reserved. // #import <Foundation/Foundation.h> #import "NSManagedObject+Explain.h" #import "NSManagedObject+Magic.h" @interface CoreDataUtil : NSObject @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; + (void)launch; @end
// CoreDataUtil.m
// // CoreDataUtil.m // CoreDataUtil // // Created by marujun on 14-1-13. // Copyright (c) 2014年 jizhi. All rights reserved. // #import "CoreDataUtil.h" NSManagedObjectContext *globalManagedObjectContext_util; NSManagedObjectModel *globalManagedObjectModel_util; @implementation CoreDataUtil @synthesize managedObjectContext_util = _managedObjectContext_util; @synthesize managedObjectModel_util = _managedObjectModel_util; @synthesize persistentStoreCoordinator_util = _persistentStoreCoordinator_util; + (void)launch { static dispatch_once_t pred = 0; __strong static id coreDataUtil = nil; dispatch_once(&pred, ^{ coreDataUtil = [[self alloc] init]; }); } - (id)init { self = [super init]; if (self) { //初始化模型 [NSManagedObject asyncQueue:false actions:^{ globalManagedObjectContext_util = [self managedObjectContext]; globalManagedObjectModel_util = [self managedObjectModel]; }]; } return self; } #pragma mark - Core Data stack // Returns the managed object context for the application. - (NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext_util != nil) { return _managedObjectContext_util; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _managedObjectContext_util = [[NSManagedObjectContext alloc] init]; [_managedObjectContext_util setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext_util; } // Returns the managed object model for the application. - (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel_util != nil) { return _managedObjectModel_util; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"models" withExtension:@"momd"]; _managedObjectModel_util = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel_util; } // Returns the persistent store coordinator for the application. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator_util != nil) { return _persistentStoreCoordinator_util; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"models.sqlite"]; NSError *error = nil; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, //[NSNumber numberWithBool:YES], NSIgnorePersistentStoreVersioningOption, nil]; _persistentStoreCoordinator_util = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator_util addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); // reset models data when core data change [userDefaults removeObjectForKey:@"AllAuthData"]; [userDefaults synchronize]; [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]; _persistentStoreCoordinator_util = nil; return [self persistentStoreCoordinator]; } return _persistentStoreCoordinator_util; } #pragma mark - Application's Documents directory // Returns the URL to the application's Documents directory. - (NSURL *)applicationDocumentsDirectory { return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } @end
// NSManagedObject+Explain.h
// // NSManagedObject+Explain.h // CoreDataUtil // // Created by marujun on 14-1-13. // Copyright (c) 2014年 jizhi. All rights reserved. // #import <CoreData/CoreData.h> @interface NSManagedObject (Explain) //异步执行任务 + (void)addObject_async:(NSDictionary *)dictionary toTable:(NSString *)tableName complete:(void (^)(NSManagedObject *object))complete; + (void)addObjectsFromArray_async:(NSArray *)otherArray toTable:(NSString *)tableName complete:(void (^)(NSArray *resultArray))complete; + (void)deleteObjects_async:(NSArray *)manyObject complete:(void (^)(BOOL success))complete; + (void)updateTable_async:(NSString *)tableName predicate:(NSPredicate *)predicate params:(NSDictionary *)params complete:(void (^)(NSArray *resultArray))complete; + (void)updateObject_async:(NSManagedObject *)object params:(NSDictionary *)params complete:(void (^)(NSManagedObject *object))complete; + (void)getTable_async:(NSString *)tableName predicate:(NSPredicate *)predicate complete:(void (^)(NSArray *result))complete; + (void)getTable_async:(NSString *)tableName actions:(void (^)(NSFetchRequest *request))actions complete:(void (^)(NSArray *result))complete; + (void)getTable_async:(NSString *)tableName predicate:(NSPredicate *)predicate sortDescriptors:(NSArray *)sortDescriptors complete:(void (^)(NSArray *result))complete; //同步执行任务 + (NSManagedObject *)addObject_sync:(NSDictionary *)dictionary toTable:(NSString *)tableName; + (NSArray *)addObjectsFromArray_sync:(NSArray *)otherArray toTable:(NSString *)tableName; + (BOOL)deleteObjects_sync:(NSArray *)manyObject; + (NSArray *)updateTable_sync:(NSString *)tableName predicate:(NSPredicate *)predicate params:(NSDictionary *)params; + (NSManagedObject *)updateObject_sync:(NSManagedObject *)object params:(NSDictionary *)params; + (NSArray *)getTable_sync:(NSString *)tableName predicate:(NSPredicate *)predicate; + (NSArray *)getTable_sync:(NSString *)tableName actions:(void (^)(NSFetchRequest *request))actions; + (NSArray *)getTable_sync:(NSString *)tableName predicate:(NSPredicate *)predicate sortDescriptors:(NSArray *)sortDescriptors; //是否在异步队列中操作数据库 + (void)asyncQueue:(BOOL)async actions:(void (^)(void))actions; @end
// NSManagedObject+Explain.m
// // NSManagedObject+Explain.m // CoreDataUtil // // Created by marujun on 14-1-13. // Copyright (c) 2014年 jizhi. All rights reserved. // #import "NSManagedObject+Explain.h" #import "CoreDataUtil.h" #define SuppressPerformSelectorLeakWarning(Stuff) \ do { \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ Stuff; \ _Pragma("clang diagnostic pop") \ } while (0) static dispatch_queue_t myCustomQueue; extern NSManagedObjectContext *globalManagedObjectContext_util; extern NSManagedObjectModel *globalManagedObjectModel_util; @implementation NSManagedObject (Explain) //异步执行任务 + (void)addObject_async:(NSDictionary *)dictionary toTable:(NSString *)tableName complete:(void (^)(NSManagedObject *object))complete { [self asyncQueue:true actions:^{ __block NSManagedObject *oneObject = [self addObject:dictionary toTable:tableName]; [self save:^(NSError *error) { error?oneObject=nil:nil; }]; if (complete) { complete(oneObject); } }]; } + (void)addObjectsFromArray_async:(NSArray *)otherArray toTable:(NSString *)tableName complete:(void (^)(NSArray *resultArray))complete { [self asyncQueue:true actions:^{ __block NSArray *resultArray = [self addObjectsFromArray:otherArray toTable:tableName]; [self save:^(NSError *error) { error?resultArray=@[]:nil; }]; if (complete) { complete(resultArray); } }]; } + (void)deleteObjects_async:(NSArray *)manyObject complete:(void (^)(BOOL success))complete { [self asyncQueue:true actions:^{ [self deleteObjects:manyObject]; __block BOOL success = true; [self save:^(NSError *error) { error?success=false:true; }]; if (complete) { complete(success); } }]; } + (void)updateTable_async:(NSString *)tableName predicate:(NSPredicate *)predicate params:(NSDictionary *)params complete:(void (^)(NSArray *resultArray))complete { [self asyncQueue:true actions:^{ __block NSArray *resultArray = [self updateTable:tableName predicate:predicate params:params]; [self save:^(NSError *error) { error?resultArray=@[]:nil; }]; if (complete) { complete(resultArray); } }]; } + (void)updateObject_async:(NSManagedObject *)object params:(NSDictionary *)params complete:(void (^)(NSManagedObject *object))complete { [self asyncQueue:true actions:^{ __block NSManagedObject *oneObject = [self updateObject:object params:params]; [self save:^(NSError *error) { error?oneObject=nil:nil; }]; if (complete) { complete(oneObject); } }]; } + (void)getTable_async:(NSString *)tableName predicate:(NSPredicate *)predicate complete:(void (^)(NSArray *result))complete { [self getTable_async:tableName predicate:predicate sortDescriptors:nil complete:complete]; } + (void)getTable_async:(NSString *)tableName actions:(void (^)(NSFetchRequest *request))actions complete:(void (^)(NSArray *result))complete { [self asyncQueue:true actions:^{ NSArray *resultArr = [self getTable:tableName predicate:nil sortDescriptors:nil actions:actions]; if (complete) { complete(resultArr); } }]; } + (void)getTable_async:(NSString *)tableName predicate:(NSPredicate *)predicate sortDescriptors:(NSArray *)sortDescriptors complete:(void (^)(NSArray *result))complete { [self asyncQueue:true actions:^{ NSArray *resultArr = [self getTable:tableName predicate:predicate sortDescriptors:sortDescriptors actions:nil]; if (complete) { complete(resultArr); } }]; } //同步执行任务 + (NSManagedObject *)addObject_sync:(NSDictionary *)dictionary toTable:(NSString *)tableName { __block NSManagedObject *oneObject = nil; [self asyncQueue:false actions:^{ oneObject = [self addObject:dictionary toTable:tableName]; [self save:^(NSError *error) { error?oneObject=nil:nil; }]; }]; return oneObject; } + (NSArray *)addObjectsFromArray_sync:(NSArray *)otherArray toTable:(NSString *)tableName { __block NSArray *resultArr = nil; [self asyncQueue:false actions:^{ resultArr = [self addObjectsFromArray:otherArray toTable:tableName]; [self save:^(NSError *error) { error?resultArr=@[]:nil; }]; }]; return resultArr; } + (BOOL)deleteObjects_sync:(NSArray *)manyObject { __block BOOL success = true; [self asyncQueue:false actions:^{ [self deleteObjects:manyObject]; [self save:^(NSError *error) { error?success=false:true; }]; }]; return success; } + (NSArray *)updateTable_sync:(NSString *)tableName predicate:(NSPredicate *)predicate params:(NSDictionary *)params { __block NSArray *resultArray = nil; [self asyncQueue:false actions:^{ resultArray = [self updateTable:tableName predicate:predicate params:params]; [self save:^(NSError *error) { error?resultArray=@[]:nil; }]; }]; return resultArray; } + (NSManagedObject *)updateObject_sync:(NSManagedObject *)object params:(NSDictionary *)params { __block NSManagedObject *oneObject = nil; [self asyncQueue:false actions:^{ oneObject = [self updateObject:object params:params]; [self save:^(NSError *error) { error?oneObject=nil:nil; }]; }]; return oneObject; } + (NSArray *)getTable_sync:(NSString *)tableName predicate:(NSPredicate *)predicate { return [self getTable_sync:tableName predicate:predicate sortDescriptors:nil]; } + (NSArray *)getTable_sync:(NSString *)tableName actions:(void (^)(NSFetchRequest *request))actions { __block NSArray *resultArr = nil; [self asyncQueue:false actions:^{ resultArr = [self getTable:tableName predicate:nil sortDescriptors:nil actions:actions]; }]; return resultArr; } + (NSArray *)getTable_sync:(NSString *)tableName predicate:(NSPredicate *)predicate sortDescriptors:(NSArray *)sortDescriptors { __block NSArray *resultArr = nil; [self asyncQueue:false actions:^{ resultArr = [self getTable:tableName predicate:predicate sortDescriptors:sortDescriptors actions:nil]; }]; return resultArr; } //扩展方法 + (NSString *)upHeadString:(NSString *)string { return [[[string substringToIndex:1] uppercaseString] stringByAppendingString:[string substringFromIndex:1]]; } - (void)setContentDictionary:(NSDictionary *)dictionary { for (NSString *key in [dictionary allKeys]) { id value = [dictionary objectForKey:key]; if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSDate class]]){ @try { [self setValue:value forKey:key]; } @catch (NSException *exception) { NSLog(@"解析基本类型出错了-->%@",exception); } }else if ([value isKindOfClass:[NSDictionary class]]){ @try { NSEntityDescription *entityDescirp = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:globalManagedObjectContext_util]; NSRelationshipDescription *relationshipDescrip = [entityDescirp.relationshipsByName objectForKey:key]; NSString *tableName = relationshipDescrip.destinationEntity.name; NSManagedObject *object = [NSManagedObject addObject:value toTable:tableName]; [self setValue:object forKey:key]; } @catch (NSException *exception) { NSLog(@"解析字典出错了-->%@",exception); } }else if ([value isKindOfClass:[NSArray class]]){ @try { for (NSDictionary *oneJsonObject in value) { NSEntityDescription *entiDescirp = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:globalManagedObjectContext_util]; NSRelationshipDescription *relationshipDescrip = [entiDescirp.relationshipsByName objectForKey:key]; NSString *tableName = relationshipDescrip.destinationEntity.name; NSManagedObject *object = [NSManagedObject addObject:oneJsonObject toTable:tableName]; SEL addSelector = NSSelectorFromString([NSString stringWithFormat:@"add%@Object:",[NSManagedObject upHeadString:key]]); SuppressPerformSelectorLeakWarning([self performSelector:addSelector withObject:object]); } } @catch (NSException *exception) { NSLog(@"解析数组出错了-->%@",exception); } } } } //在当前队列执行任务 + (NSManagedObject *)addObject:(NSDictionary *)dictionary toTable:(NSString *)tableName { NSManagedObject *oneObject = nil; Class class = NSClassFromString(tableName); NSEntityDescription *entityDescrip = [[globalManagedObjectModel_util entitiesByName] objectForKey:tableName]; oneObject = [[class alloc] initWithEntity:entityDescrip insertIntoManagedObjectContext:globalManagedObjectContext_util]; [oneObject setContentDictionary:dictionary]; return oneObject; } + (NSArray *)addObjectsFromArray:(NSArray *)otherArray toTable:(NSString *)tableName { NSMutableArray *resultArray = [[NSMutableArray alloc] init]; Class class = NSClassFromString(tableName); NSEntityDescription *entityDescrip = [[globalManagedObjectModel_util entitiesByName] objectForKey:tableName]; for (NSDictionary *dictionary in otherArray) { NSManagedObject *oneObject = [[class alloc] initWithEntity:entityDescrip insertIntoManagedObjectContext:globalManagedObjectContext_util]; [oneObject setContentDictionary:dictionary]; [resultArray addObject:oneObject]; } return [resultArray copy]; } + (NSArray *)updateTable:(NSString *)tableName predicate:(NSPredicate *)predicate params:(NSDictionary *)params { //查询数据 NSArray *queryArr = [self getTable:tableName predicate:predicate sortDescriptors:nil actions:nil]; //有匹配的记录时则更新记录 if(queryArr && queryArr.count){ for (NSManagedObject *object in queryArr.copy) { [self updateObject:object params:params]; } } else //没有匹配的记录时添加记录 { queryArr = @[[self addObject:params toTable:tableName]]; } return queryArr; } + (NSManagedObject *)updateObject:(NSManagedObject *)object params:(NSDictionary *)params { for (NSString *key in params.allKeys) { id value = [params objectForKey:key]; if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSDate class]]){ @try { [object setValue:value forKey:key]; } @catch (NSException *exception) { NSLog(@"key值出错了-->%@",exception); } }else if ([value isKindOfClass:[NSDictionary class]]){ @try { NSManagedObject *otherObject = [object valueForKey:key]; if(otherObject){ [self updateObject:otherObject params:value]; }else{ NSEntityDescription *entityDescirp = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:globalManagedObjectContext_util]; NSRelationshipDescription *relationshipDescrip = [entityDescirp.relationshipsByName objectForKey:key]; NSString *tableName = relationshipDescrip.destinationEntity.name; otherObject = [NSManagedObject addObject:value toTable:tableName]; [object setValue:otherObject forKey:key]; } } @catch (NSException *exception) { NSLog(@"解析字典出错了-->%@",exception); } }else if ([value isKindOfClass:[NSArray class]]){ @try { NSArray *objectArray = [[object valueForKey:key] allObjects]; for (int index=0; index<[(NSArray *)value count]; index++) { NSDictionary *tempParams = [(NSArray *)value objectAtIndex:index]; if (objectArray && index<objectArray.count) { [self updateObject:objectArray[index] params:tempParams]; }else{ NSEntityDescription *entiDescirp = [NSEntityDescription entityForName:NSStringFromClass([object class]) inManagedObjectContext:globalManagedObjectContext_util]; NSRelationshipDescription *relationshipDescrip = [entiDescirp.relationshipsByName objectForKey:key]; NSString *tableName = relationshipDescrip.destinationEntity.name; NSManagedObject *tempObject = [self addObject:tempParams toTable:tableName]; SEL addSelector = NSSelectorFromString([NSString stringWithFormat:@"add%@Object:",[NSManagedObject upHeadString:key]]); SuppressPerformSelectorLeakWarning([object performSelector:addSelector withObject:tempObject]); } } } @catch (NSException *exception) { NSLog(@"解析数组出错了-->%@",exception); } } } return object; } + (NSArray *)getTable:(NSString *)tableName predicate:(NSPredicate *)predicate sortDescriptors:(NSArray *)sortDescriptors actions:(void (^)(NSFetchRequest *request))actions { NSArray *resultArr = @[]; NSFetchRequest *request = [[NSFetchRequest alloc]init]; NSEntityDescription *description = [NSEntityDescription entityForName:tableName inManagedObjectContext:globalManagedObjectContext_util]; [request setEntity:description]; if (predicate) { [request setPredicate:predicate]; } if (sortDescriptors && sortDescriptors.count) { [request setSortDescriptors:sortDescriptors]; } actions?actions(request):nil; @try { @synchronized(globalManagedObjectContext_util) { resultArr = [globalManagedObjectContext_util executeFetchRequest:request error:nil]; } } @catch (NSException *exception) { NSLog(@"查询数据库出错了-->%@",exception); } return resultArr; } + (void)save:(void (^)(NSError *error))complete { NSError *error; @synchronized(globalManagedObjectContext_util) { if (![globalManagedObjectContext_util save:&error]) { // Update to handle the error appropriately. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); } } } + (void)deleteObjects:(NSArray *)manyObject { @synchronized(globalManagedObjectContext_util) { for (NSManagedObject *object in manyObject){ [globalManagedObjectContext_util deleteObject:object]; } } } //是否在异步队列中操作数据库 + (void)asyncQueue:(BOOL)async actions:(void (^)(void))actions { static int specificKey; if (myCustomQueue == NULL) { myCustomQueue = dispatch_queue_create("com.jizhi.coredata", DISPATCH_QUEUE_SERIAL); //生成一个串行队列 CFStringRef specificValue = CFSTR("com.jizhi.coredata"); dispatch_queue_set_specific(myCustomQueue, &specificKey, (void*)specificValue,(dispatch_function_t)CFRelease); } NSString *retrievedValue = (NSString *)CFBridgingRelease(dispatch_get_specific(&specificKey)); if (retrievedValue && [retrievedValue isEqualToString:@"com.jizhi.coredata"]) { actions ? actions() : nil; }else{ if(async){ dispatch_async(myCustomQueue, ^{ actions ? actions() : nil; }); }else{ dispatch_sync(myCustomQueue, ^{ actions ? actions() : nil; }); } } } @end
// NSManagedObject+Magic.h
// // NSManagedObject+Magic.h // CoreDataUtil // // Created by marujun on 14-1-13. // Copyright (c) 2014年 jizhi. All rights reserved. // #import <CoreData/CoreData.h> /*导入所有通过model生成的SubClass*/ #import "User.h" #import "Bank.h" @interface NSSet (TCNSManagedObjectMethods) // 排序下 - (NSArray *)sortObjects; @end @interface NSManagedObject (Magic) /*获取表中所有数据*/ + (NSArray *)getTable:(NSString *)tableName; /*清空表*/ + (void)cleanTable:(NSString *)tableName; @end
// NSManagedObject+Magic.m
// // NSManagedObject+Magic.m // CoreDataUtil // // Created by marujun on 14-1-13. // Copyright (c) 2014年 jizhi. All rights reserved. // #import "NSManagedObject+Magic.h" #import "CoreDataUtil.h" @implementation NSSet (TCNSManagedObjectMethods) - (NSArray *)sortObjects { return [[self allObjects] sortedArrayUsingComparator:^NSComparisonResult(NSManagedObject *obj1, NSManagedObject *obj2) { if (obj1.index.intValue > obj2.index.intValue) { return (NSComparisonResult)NSOrderedDescending; }else if (obj1.index.intValue < obj2.index.intValue){ return NSOrderedAscending; } return NSOrderedSame; }]; } @end extern NSManagedObjectContext *globalManagedObjectContext; extern NSManagedObjectModel *globalManagedObjectModel; @implementation NSManagedObject (Magic) + (NSArray *)getTable:(NSString *)tableName { NSArray *resultArr = [NSManagedObject getTable_sync:tableName predicate:nil]; return (resultArr && resultArr.count != 0)?resultArr:nil; } + (void)cleanTable:(NSString *)tableName { NSArray *array = [self getTable_sync:tableName predicate:nil]; [self deleteObject_sync:array]; } @end