数据缓存——CoreData的使用

CoreData的使用

Demo下载地址


1、使用到的对象

(1)NSManagedObjectContext

操作数据库的上下文(数据库,获取与存储),即负责应用与数据库之间的交互

作用:插入数据、查询数据、删除数据

(2)NSManagedObjectModel

 数据库中所有表格和他们的联系(数据模型),即代表CoreData模型文件,相当于实体

 作用:添加实体的属性与类型设置,建立属性之间的关系

 关联:数据模型地址(NSURL)

 (3)NSPersistentStoreCoordinator/NSPersistentStore

 数据库存放方式(中介、存储数据),即处理数据存储的链接

 作用:设置数据存储的名字、位置、存储方式、存储时机

 关联:数据模型(NSManagedObjectModel)、存储位置(NSURL)、存储方式(NSSQLiteStoreType)、存储时机(NSString)、存储迁移(NSDictionary)

(4)NSManagedObject

 相当于数据库中的表格的记录(数据对象,管理属性)

(5)NSFetchRequest

 相当于查询语句(请求数据,排序/条件/数量)

 关联:查询条件(NSPredicate)、查询排序(NSSortDescriptor)、查询数量(NSNumber)

(6)NSEntityDescription(实体结构)
相当于表格结构


注意:后缀为.xcdatamodeld的包,里面是.xcdatamodel文件,用数据模型编辑器编辑,编译后为.momd.mom文件。

 

二、实操

(1)创建CoreData的Model。






(2)创建实体,并设置实体中的属性、属性类型。


(3)创建与实体对应的数据对象,以便于管理属性对象。






 

三、版本升级

当数据库版本升级时,即版本迭代后,数据库中的原实体新增加了属性,或新增加了实体,必须做相应的处理,以避免crash情况。

(1)新增属性,或新增实体后出现异常提示

 


(2)解决:增加版本号处理。(注意:使用系统默认生成的新版本名称,切忌进行修改)




 

四、代码

(1)封装类

.h文件
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
 
@interface CoreDataManager : NSObject
 
/**
*  单例模式
*
* @return CoreDataManager
*/
+ (CoreDataManager *)shareManager;
 
/**
 *  创建空的表映射对象
 *
 * @param entityName entityName实体描述名
 *
 * @return id实体类对象
 */
-(id)createEmptyObjectWithEntityName:(NSString *)entityName;
 
/**
 *  查询托管对象上下文中的对象
 *
 * @param predicate        predicate查询条件
 * @param sortDescriptions sortDescriptions排序条件
 * @param entityName       entityName实体描述名
 * @param limitNum         limitNum返回总个数
 *
 * @return NSArray
 */
- (NSArray *)getListWithPredicate:(NSPredicate*)predicate sortDescriptors:(NSArray *)sortDescriptions entityName:(NSString*)entityName limitNum:(NSNumber *)limitNum;
 
/**
 *  删除托管对象上下文中的一个对象
 *
 * @param object object需要删除的任意对象
 *
 * @return BOOL
 */
- (BOOL)deleteObject:(NSManagedObject*)object;
 
/**
 *  删除托管对象上下文中的一个对象
 *
 * @param object   object需要删除的任意对象
 * @param complete complete block回调
 */
- (void)deleteObject:(NSManagedObject*)object complete:(void (^)(BOOL isSuccess))complete;
 
/**
 *  删除托管对象上下文中的所有对象
 *
 * @param entityName entityName实体描述名
 *
 * @return BOOL
 */
-(BOOL)deleteAllObjectWithEntityName:(NSString *)entityName;
 
/**
 *  删除托管对象上下文中的所有对象
 *
 * @param entityName entityName实体描述名
 * @param complete   complete block回调
 */
- (void)deleteAllObjectWithEntityName:(NSString*)entityName complete:(void (^)(BOOL isSuccess))complete;
 
/**
 *  保存托管对象上下文中的更改
 *
 * @return BOOL
 */
- (BOOL)save;
 
/**
 *  保存托管对象上下文中的更改
 *
 * @param complete complete block回调
 */
- (void)save:(void (^)(BOOLisSuccess))complete;
 
@end

.m文件
#import "CoreDataManager.h"
 
// 数据库名称
static NSString *const CoreDataSQLiteName =@"CoreDataCache.sqlite";
 
@interface CoreDataManager ()
 
@property (nonatomic, strong)NSManagedObjectContext *objectContext; // 托管对象上下文
 
@end
 
@implementation CoreDataManager
 
/// 数据库存储路径(document)
NSString *GetDocumentPathFileName(NSString*lpFileName)
{
   NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
   if (paths && 0 != paths.count)
    {
       NSString *documentsDirectory = [paths objectAtIndex:0];
       if (documentsDirectory && 0 != documentsDirectory.length)
       {
           if (lpFileName && 0 != lpFileName.length)
           {
                NSString *filePath =[documentsDirectory stringByAppendingPathComponent:lpFileName];
                return filePath;
           }
       }
    }
   
   return nil;
}
 
- (id)init
{
   self = [super init];
   if (self)
    {
       if (!self.objectContext)
       {
           // 指定存储数据文件(CoreData是建立在SQLite之上的,文件后缀名为:xcdatamodel)
           NSString *persistentStorePath =GetDocumentPathFileName(CoreDataSQLiteName);
           NSURL *storeUrl = [NSURL fileURLWithPath:persistentStorePath];
 
           // 数据迁移
           NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                     [NSNumbernumberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                     [NSNumbernumberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
           
           
           // 创建托管对象模型
           NSURL *modelURL = [[NSBundle mainBundle]URLForResource:@"CacheModel" withExtension:@"momd"];
           NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelURL];
           
           // 创建持久化存储协调器,并使用SQLite数据库做持久化存储
           NSPersistentStoreCoordinator *persistentStoreCoordinator =[[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:managedObjectModel];
           
           NSError *error = nil;
           NSPersistentStore *persistentStore = [persistentStoreCoordinatoraddPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrloptions:options error:&error];
 
           // 创建托管对象上下文
           if (persistentStore && !error)
           {
                NSManagedObjectContext*managedObjectContext = [[NSManagedObjectContext alloc] init];
                [managedObjectContextsetPersistentStoreCoordinator:persistentStoreCoordinator];
               
                self.objectContext =managedObjectContext;
           }
           else
           {
                NSLog(@"failed to addpersistent store with type to persistent store coordinator");
                NSLog(@"Unresolved error%@, %@", error, [error userInfo]);
           }
       }
    }
   
   return self;
}
 
 
+ (CoreDataManager *)shareManager
{
   static CoreDataManager *staticCoreDataManager;
   static dispatch_once_t onceToken;
   
   dispatch_once(&onceToken, ^{
       staticCoreDataManager = [[self alloc] init];
       assert(staticCoreDataManager != nil);
   });
   
   return staticCoreDataManager;
}
 
-(id)createEmptyObjectWithEntityName:(NSString *)entityName
{
   NSManagedObject *managerObject = [NSEntityDescriptioninsertNewObjectForEntityForName:entityNameinManagedObjectContext:self.objectContext];
   return managerObject;
}
 
- (NSArray*)getListWithPredicate:(NSPredicate *)predicate sortDescriptors:(NSArray*)sortDescriptions entityName:(NSString *)entityName limitNum:(NSNumber*)limitNum
{
   NSError *error = nil;
   
   // 创建取回数据请求
   NSFetchRequest *fetchRequest = [NSFetchRequestfetchRequestWithEntityName:entityName];
   
    //设置查询条件
   [fetchRequest setPredicate:predicate];
   
   // 设置排序条件
   [fetchRequest setSortDescriptors:sortDescriptions];
   
   // 查询条件的总数
   [fetchRequest setFetchLimit:[limitNum intValue]];
   
   // 执行获取数据请求,返回数组
   NSArray *fetchResult = [self.objectContextexecuteFetchRequest:fetchRequest error:&error];
   
   return fetchResult;
}
 
- (BOOL)deleteObject:(NSManagedObject*)object
{
   [self.objectContext deleteObject:object];
   
   BOOL isSuccess = [self save];
   return isSuccess;
}
 
- (void)deleteObject:(NSManagedObject*)object complete:(void (^)(BOOL isSuccess))complete
{
   BOOL isSuccess = [self deleteObject:object];
   if (complete)
    {
       complete(isSuccess);
    }
}
 
-(BOOL)deleteAllObjectWithEntityName:(NSString *)entityName
{
   NSArray *allObjects = [self getListWithPredicate:nil sortDescriptors:nilentityName:entityName limitNum:nil];
   
   if (allObjects && 0 != allObjects.count)
    {
       for (NSManagedObject *object in allObjects)
       {
           [self.objectContext deleteObject:object];
       }
       
       BOOL isSuccess = [self save];
       return isSuccess;
    }
   
   return NO;
}
 
-(void)deleteAllObjectWithEntityName:(NSString *)entityName complete:(void(^)(BOOL isSuccess))complete
{
   BOOL isSuccess = [self deleteAllObjectWithEntityName:entityName];
   if (complete)
    {
       complete(isSuccess);
    }
}
 
- (BOOL)save
{
   NSError *error = nil;
   BOOL isSuccess = [self.objectContext save:&error];
   return isSuccess;
}
 
- (void)save:(void (^)(BOOLisSuccess))complete
{
   BOOL isSuccess = [self save];
   if (complete)
    {
       complete(isSuccess);
    }
}
 
@end


(2)调用封装类

导入头文件

#import "CoreDataManager.h"
#import "NameCache.h"


搜索/删除全部/删除指定/保存

- (void)search
{
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"cacheName== %@", @"zhangshaoyu"];
   
   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"cacheTime" ascending:NO];
   NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
   
   NSArray *array = [[CoreDataManager shareManager]getListWithPredicate:predicate sortDescriptors:sortDescriptionsentityName:@"NameCache" limitNum:[NSNumber numberWithInt:10]];
   
   NSLog(@"array %@", array);
   for (NameCache *cache in array)
    {
       NSString *name = cache.cacheName;
       NSString *key = cache.cacheKey;
       NSDate *date = cache.cacheTime;
       
       NSData *data = cache.cacheImage;
       
       NSLog(@"name = %@, key = %@, date = %@, data = %@", name, key,date, data);
    }
}

- (void)deleteAll
{
//   // 保存区域信息前先将已有信息删除,避免造成数据重复
//   [[CoreDataManager shareManager]deleteAllObjectWithEntityName:@"NameCache"];
   
   [[CoreDataManager shareManager]deleteAllObjectWithEntityName:@"NameCache" complete:^(BOOL isSuccess){
        NSLog(@"%@", [NSStringstringWithFormat:@"delete all:%@", (isSuccess ? @"success": @"failue")]);
   }];
}

- (void)delete
{
   // 删除某个
   NSPredicate *predicate = [NSPredicatepredicateWithFormat:@"cacheName == %@", @"zhangshaoyu"];
    NSSortDescriptor*sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cacheTime"ascending:NO];
   NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
   NSArray *array = [[CoreDataManager shareManager] getListWithPredicate:predicatesortDescriptors:sortDescriptions entityName:@"NameCache"limitNum:[NSNumber numberWithInt:10]];
   
   NSLog(@"array %@", array);
   for (NameCache *cache in array)
    {
       NSString *name = cache.cacheName;
       NSString *key = cache.cacheKey;
       NSDate *date = cache.cacheTime;
       
       NSData *data = cache.cacheImage;
       
       NSLog(@"name = %@, key = %@, date = %@, data = %@", name, key,date, data);
       
//       [[CoreDataManager shareManager] deleteObject:cache];
       
       [[CoreDataManager shareManager] deleteObject:cache complete:^(BOOLisSuccess) {
           NSLog(@"%@", [NSString stringWithFormat:@"deleteobject:%@", (isSuccess ? @"success" : @"failue")]);
       }];
    }
}

- (void)save
{
   NSArray *array = [NSArray arrayWithObjects:@"zhangshaoyu",@"herman", @"weishijiajie", nil];
   
   // 保存新信息
   for (NSInteger index = 0; index < array.count; index++)
    {
       NSString *name = array[index];
       NSString *key = [NSString stringWithFormat:@"%ld", index];
       
       NameCache *cache = [[CoreDataManager shareManager]createEmptyObjectWithEntityName:@"NameCache"];
       [cache setCacheName:name];
       [cache setCacheKey:key];
       [cache setCacheTime:[NSDate date]];       
       
       NSData *image = [[NSData alloc] initWithContentsOfURL:[NSURLURLWithString:@"http://gtb.baidu.com/HttpService/get?p=dHlwZT1pbWFnZS9qcGVnJm49dmlzJnQ9YWRpbWcmYz10YjppZyZyPTEzMjA2ODYxODAsMzY1MTE3NTc5MgAAAA=="]];
       [cache setCacheImage:image];
       
//       [[CoreDataManager shareManager] save];
       
       [[CoreDataManager shareManager] save:^(BOOL isSuccess) {
           NSLog(@"%@", [NSString stringWithFormat:@"saveobject:%@", (isSuccess ? @"success" : @"failue")]);
       }];
    }
}


五、说明

前面所提到的基本上是关于Core Data框架的入门。

Core Data还远不止这些功能,它还支持自动撤销机制,一对多关联等。

待续:自动撤销、关联、数据迁移、数据查看、第三方库使用……。



猜你喜欢

转载自blog.csdn.net/potato512/article/details/51165437