[原創文章,轉載請提前說明并附上原文鏈接]
CoreData是iOS5后,蘋果提供的原生的用于對象化管理數據并且持久化的框架。CoreData本質上是將底層數據庫封裝成對象進行管理。但數據庫實際上只是CoreData的一個功能,并不是全部功能。在iOS開發中,除了可以使用CoreData進行數據管理,還可以使用SQLite進行內存管理。并且有封裝好SQLite代碼的OC框架FMDB給我們使用。具體看我上篇文章。SQLite重要框架FMDB的使用.但對比SQLite,CoreData有下面幾個優勢。第一是CoreData作為蘋果提供的原生框架,在內存方法比SQLite有性能上的優勢。第二是CoreData操作數據不需要使用SQLite代碼,使用方便。第三是CoreData把數據用面向對象方式進行管理,操作數據庫更方便。
CoreData的核心是Core Data stack(技術棧堆)。CoreData就是依靠Core Data stack中的幾個對象進行數據操作的。這幾對象是:
NSManagedObjectContext ,管理對象的上下文: 負責管理模型對象的一個集合,
NSManagedObjectModel 被管理的對象模型
NSPersistentStoreCoordinator 存儲調度器: 負責將數據保存到磁盤,
NSPersistentStore用于保存模型數據,受NSPersistentStoreCoordinator 存儲調度器的操控。
這三個對象的關系如下面圖片所示,蘋果官方給出了這幾個對向關系的圖解。簡單理解起來就是最上面的NSManagedObjectContext負責管理對象模型。然后將管理的對象模型發送給NSPersistentStoreCoordinator 存儲調度器,存儲調度器通過NSPersistentStore操作SQLite語句,將數據持久化到本地,保存到StoryFile中。
數據庫的使用也很簡單,我們只需要在創建項目文件的時候勾選使用coreData的選項,系統就會幫我們創建一個包含CoreData的項目文件。
然后在界面上就會出現下面的變化。我們點擊添加屬性按鈕,就能在數據庫中給數據模型添加屬性。
添加完數據庫后我們進行下面操作就能將數據模型轉為代碼文件。
做完上面操作之后我們就能對數據庫模型進行操作了。
我們在操作數據,對數據進行增刪改查的時候,都需要用到Core Data stack這個工具。我們自己可以封裝一個Core Data stack,這樣更能加深我們對Core Data stack這個工具的理解。
下面是封裝一個工具類的代碼:
首先是該工具類的.h文件中的代碼
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#define KXBCoreManagerInstance [HMCoreDataStackManager shareInstance]
@interface HMCoreDataStackManager : NSObject
///單例
+(HMCoreDataStackManager*)shareInstance;
///管理對象上下文
@property(strong,nonatomic)NSManagedObjectContext *managerContenxt;
///模型對象
@property(strong,nonatomic)NSManagedObjectModel *managerModel;
///存儲調度器
@property(strong,nonatomic)NSPersistentStoreCoordinator *maagerDinator;
//保存數據的方法
-(void)save;
@end
然后是.m文件中的代碼
#import "HMCoreDataStackManager.h"
@implementation HMCoreDataStackManager
///單例的實現
+(HMCoreDataStackManager*)shareInstance
{
static HMCoreDataStackManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[HMCoreDataStackManager alloc]init];
});
return instance;
}
-(NSURL*)getDocumentUrlPath
{
///獲取文件位置
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]
;
}
//懶加載managerContenxt
-(NSManagedObjectContext *)managerContenxt
{
if (_managerContenxt != nil) {
return _managerContenxt;
}
_managerContenxt = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
///設置存儲調度器
[_managerContenxt setPersistentStoreCoordinator:self.maagerDinator];
return _managerContenxt;
}
///懶加載模型對象
-(NSManagedObjectModel *)managerModel
{
if (_managerModel != nil) {
return _managerModel;
}
_managerModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return _managerModel;
}
-(NSPersistentStoreCoordinator *)maagerDinator
{
if (_maagerDinator != nil) {
return _maagerDinator;
}
_maagerDinator = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:self.managerModel];
//添加存儲器
/**
* type:一般使用數據庫存儲方式NSSQLiteStoreType
* configuration:配置信息 一般無需配置
* URL:要保存的文件路徑
* options:參數信息 一般無需設置
*/
//拼接url路徑
NSURL *url = [[self getDocumentUrlPath]URLByAppendingPathComponent:@"sqlit.db" isDirectory:YES];
[_maagerDinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];
return _maagerDinator;
}
-(void)save
{ ///保存數據
[self.managerContenxt save:nil];
}
通過上面代碼可以看出封裝一個Core Data stack類并不是很難,我們需要做的是創建一個單例,然后懶加載一個NSManagedObjectContext,并給NSManagedObjectContext添加存儲調度器NSPersistentStoreCoordinator。
懶加載存儲調度器的時候給存儲調度器添加存儲器PersistentStore。在最后提供一個保存數據的方法,每次我們修改數據庫中文件數據的時候,都需要用Core Data stack調用save方法保存數據。
CoreData關于數據的操作無非就是增刪改查。增刪改查我們同樣需要使用自定義的Core Data stack工具類。
增加數據:
Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" in Managed ObjectContext : kManagedObjectContext.managedObjectContext];
p.age = @(13);
p.name = @"張三";
[kManagedObjectContext save];
刪除數據:
//1.創建一個查詢請求
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
//2.創建查詢謂詞(查詢條件)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"張三"];
//3.給查詢請求設置謂詞
request.predicate = predicate;
//4.查詢數據
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil];
//5.刪除數據
[kManagedObjectContext.managedObjectContext deleteObject:arr.firstObject];
//6.同步到數據庫 [kManagedObjectContext save];
修改數據:
//1.創建一個查詢請求
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
//2.創建查詢謂詞(查詢條件)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"張三"];
//3.給查詢請求設置謂詞
request.predicate = predicate;
//4.查詢數據
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil];
//5.改變數據
arr.firstObject.name = @"李四";
arr.firstObject.age = @(18);
//6.同步到數據庫
[kManagedObjectContext save];
查詢數據:
//1.創建一個查詢請求
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
//2.創建查詢謂詞(查詢條件)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"張三"];
//3.給查詢請求設置謂詞
request.predicate = predicate;
//4.查詢數據
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; NSLog(@"%@====%@",arr.firstObject.name,arr.firstObject.age);
使用CoreData我們可以輕松實現很多數據的操作,例如通訊錄數據錄的增刪改查。
在這里提供一個通訊錄數據操作的demo,使用CoreData,我們能輕松地實現通訊錄功能。
CoreData實現通訊錄