1.原理部分
Core Data
是一個純粹的面向對象框架,可用于管理實體以及實體之間的關聯關系的持久化,也就是我們通常所指的數據持久化。
Core Data
底層的持久化存儲方式可以是SQLite
數據庫,也可以是XML
文檔,甚至可以直接以內存作為持久化存儲設備。
Core Data
的核心概念是實體。實體是由Core Data
管理的模型對象,它必須是NSManagedObject
類或其子類的實例。實體與實體之間存在1-1、1-N、N-N、的關聯關系,整個應用的所有實體以及實體之間的關聯關系被稱為托管對象模型NSManagedObiectModel
。
Core Data
的核心對象是托管對象上下文NSManagedObjectContext
,所有實體都處于托管對象上下文管理中,Core Data
應用對實體所做的任何增、刪、查、改操作都必須通過托管對象上下文來完成。
開發者開發的應用程序需要通過NSMannagedObjectContext
對實體進行增、刪、查、改操作,而NSMannagedObjectContext
底層與持久化存儲協調銜接,持久化存儲協調器則負責管理底層的存儲形式比如:SQLite
。
Core Data
應用中的核心API
有如下幾個。
托管對象模型
NSManagedObiectModel
:該對象負責管理整個應用的所有實體以及實體之間的關聯關系。當開發者使用Xcode
的圖形界面設計了實體與實體的關聯關系之后,需要使用該對象來加載、管理應用的托管對象模型。
持久化存儲協調器
NSPeristentStoreCoordinator
:負責管理底層的存儲文件,例如SQLite
數據庫等。
托管對象上下文
NSManagedObjectContext
:該對象是Core Data
的核心對象,應用對實體所做的任何增、刪、查、改操作都必須通過該對象來完成。
實體描述
NSEntityDescription
:該對象代表了關于某個實體的描述信息,從某種程度來說,該對象相當于實體的抽象。實體描述定義了該實體的名字、實體的實現類,并用一個集合定義了該實體包含的所有屬性。
抓取請求
NSFetchRequest
:該對象封裝了查詢實體的請求,包括程序需要查詢哪些實體、查詢條件、排序規則等。抓取請求定義了本次查詢的實體的名字、抓取請求的查詢條件,通過NSPredicate來表示
,并用一個NSArray
集合定義了所有的排序規則。
熟悉以上幾點之后,使用Core Data
持久化操作的步驟大致如下。
- 創建
NSManagedObiectModel
對象來加載管理應用的托管對象模型。 - 以
NSManagedObiectModel
對象為基礎,根據實際需要創建NSPeristentStoreCoordinator
對象,該對象確定Core Data
底層數據的存儲形式。 - 以
NSManagedObiectModel
對象為基礎,創建NSMannagedObjectContext
,該對象是Core Data
進行持久化訪問的核心對象。 - 對于普通的增、刪、查、改操作,需要分別先創建實體、刪除實體、修改實體,然后調用
NSMannagedObjectContext
對象的save:
方法將這些修改保存到底層存儲設備。 - 如果要執行查詢,則需要先創建
NSFetchRequest
對象,再調用NSMannagedObjectContext
的executeFetchRequest:error
:方法執行查詢,該方法返回所有匹配條件的實體組成的NSArray
。
2.手動配置環境
iOS允許在創建項目時勾選“Use Core Data”復選框,通過該方式創建的項目已經完成了所有Core Data
必須資源的初始化,但此處并不打算使用這種方式來初始化Core Data
項目,而是選擇從一個Empty Application
開始,手動初始化Core Data
項目,這樣便于大家真正理解Core Data
項目需要初始化哪些資源。
下面我們將開始把這個Empty Application
項目一步步改造成Core Data
項目。
具體步驟如下:
為該項目添加
CoreData.framework
框架。-
為該項目添加一個實體模型文件。單擊Xcode主菜單的"File"--->"New"--->"File"菜單項,具體如下圖:
coreData01.png 在
AppDelegate
中初始化Core Data
應用必須的核心API
對象:NSManagedObiectModel
、NSPeristentStoreCoordinator
、NSManagedObjectContext
修改應用程序委托類的接口部分,在接口部分定義上面3個核心API
的屬性,并增加一個對NSManagedObjectContext
對象執行存儲的方法、一個獲取應用Docouments
目錄下的方法。下面是修改后的接口部分代碼。
AppDelegate.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
// 定義Core Data的3個核心API的屬性
@property (readonly, strong, nonatomic) NSManagedObjectContext*
managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator*
persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@end
接下來在AppDelegate.m
中實現部分進行修改,初始化對象,并實現saveContext
方法,其中applicationDocumentsDirectory
是一個非常簡單的方法,用于獲取應用Docouments
目錄
AppDelegate.m
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// 當應用被中斷時候,將所有托管上下文中數據保存起來
[self saveContext];
}
- (void)saveContext
{
NSError *error = nil;
// 獲取應用的托管對象上下文
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
// 如果托管對象上下文中包含了未保存的修改,執行保存,如果保存失敗記錄錯誤信息
if ([managedObjectContext hasChanges] &&
![managedObjectContext save:&error])
{
NSLog(@"保存出現錯誤:%@, %@", error, [error userInfo]);
abort();
}
}
}
// 初始化應用的托管對象上下文。
- (NSManagedObjectContext *)managedObjectContext
{
// 如果_managedObjectContext已經被初始化過,直接返回該對象
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
// 獲取持久化存儲協調器
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
// 如果持久化存儲協調器不為nil
if (coordinator != nil)
{
// 創建NSManagedObjectContext對象
_managedObjectContext = [[NSManagedObjectContext alloc] init];
// 為NSManagedObjectContext對象設置持久化存儲協調器
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
// 如果_managedObjectModel已經被初始化過,直接返回該對象
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
// 獲取實體模型文件對應的NSURL
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"FKModel"
withExtension:@"momd"];
// 加載應用的實體模型文件,并初始化NSManagedObjectModel對象
_managedObjectModel = [[NSManagedObjectModel alloc]
initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
// 如果_persistentStoreCoordinator已經被初始化過,直接返回該對象
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// 獲取SQLite數據庫文件的存儲目錄
NSURL *storeURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"Books.sqlite"];
NSError *error = nil;
// 以持久化對象模型為基礎,創建NSPersistentStoreCoordinator對象
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
// 設置持久化存儲協調器底層采用SQLite存儲機制,如果設置失敗記錄錯誤信息
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(@"設置持久化存儲失敗:%@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
// 獲取應用的Documents目錄
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
}
到此Core Data
所依賴的環境基本上已經搭建完畢,應用執行增、刪、查、改操作直接調用managedObjectContext
方法即可操作。
3.設計實體模型
Xcode中找到我們創建的Core Data
文件,打開實體模型開始編輯,具體如下圖:
下面我們添加一個簡單的實體,點擊上圖走下角的Add Entity
,系統將會在ENTITIES
列表下添加一個實體,將該實體重命名為項目所需的名字,此處為Bison
PS長按Add Entity
將會顯示Add Entity
、Add Fetch Request
、Add Configuration
列表,可供選擇添加實體、抓取請求、配置。
選中Bison
實體,通過點擊上圖右下角的Add Attribute
按鈕,系統將會為該Bison
實體添加一個屬性,將該屬性重命名所需的名字,此處重命名name
,并為該屬性選擇類型,在此選String
類型,注意:此處命名首字母不能大寫哦。
PS長按Add Attribute
將會顯示Add Attribute
、Add Relationship
、Add Configuration
、Add Fetch Property列表,可供選擇添加屬性、關聯關系、抓取屬性,也可以通過 +
、—
來添加與刪除。
重復上面的操作增加一個birthDay
的屬性,改屬性為date
類型。實體設計完后,如下圖:
然后單擊Xcode主菜單的Editor
-->Create NSManagedObject Subclass
菜單項,如果系統包含倆個以上的實體,Xcode將會彈出一個對話框讓選擇腰圍哪些實體生成NSManagedObject
的子類,然后彈出對話框讓選擇NSManagedObject
的子類的存儲路徑。選完之后Create
按鈕即可。
經過上面的操作,為實體模型添加一個簡單的Bison
實體,該實體包含倆個屬性,單不包含任何關聯關系。
4.Core Data
數據的增刪查改
獲取托管對象上下文NSManagedObjectContext
之后,接下來即可通過該對象來執行增、刪、查、改操作。
- 添加實體
添加實體的步驟如下:
調用NSEntityDescription
的insertNewObjectForEntityForName:inManagedObjectContext:
靜態方法添加新實體。該方法的第1個參數為實體名,第2個參數為NSManagedObjectContext
對象。為新實體設置屬性。調用NSManagedObjectContext
對象的save:
方法執行保存。如下代碼片段:
// 控制Core Data在托管對象上下文中創建一個新實體
Bison* bison = [NSEntityDescription
insertNewObjectForEntityForName:@"Bison"
inManagedObjectContext:self.appDelegate.managedObjectContext];
// 為新實體設置屬性
bison.name = @"linbin";
bison.birth_Day = [NSDate date];
// 定義一個NSError對象,用于接受錯誤信息
NSError *error;
// 設置完實體屬性之后,調用托管對象上下文的`save:`方法將實體寫入數據庫,如果保存成功
if ([self.appDelegate.managedObjectContext save:&error])
{
[[[UIActionSheet alloc] initWithTitle:@"保存成功" delegate:nil
cancelButtonTitle:@"確定" destructiveButtonTitle:nil
otherButtonTitles: nil] showInView:self.view];
}
else
{
NSLog(@"保存FKEvent實體出錯: %@,%@" , error ,[error userInfo]);
}
- 刪除實體
刪除實體的步驟如下:
首先獲取要刪除的實體,然后調用NSManagedObjectContext
對象的deleteObject:
方法刪除實體。最后調用NSManagedObjectContext
對象的save:
方法執行保存。如下代碼:
// 獲取將要刪除的實體
Bison* deleteEvent = .....;
// 從托管對象上下文中刪除指定對象
[self.appDelegate.managedObjectContext deleteObject:deleteEvent];
NSError *error;
// 保存刪除操作,如果出現錯誤,顯示錯誤信息
if (![self.appDelegate.managedObjectContext save:&error])
{
NSLog(@"刪除FKEvent實體出錯:%@,%@",error,[error userInfo]);
}
- 修改實體
修改實體的步驟如下:
首先獲取要修改的實體,必須處于NSManagedObjectContext
管理下的實體;然后修改實體的屬性;再調用NSManagedObjectContext
對象的save:
方法執行保存。如下代碼:
// 獲取將要修改的實體
Bison* updateEvent = .....;
//修改實體的屬性
.....
//定義一個NSError對象,用于接收錯誤信息
NSError *error;
// 保存修改操作,如果出現錯誤,顯示錯誤信息
if (![self.appDelegate.managedObjectContext save:&error])
{
NSLog(@"刪除FKEvent實體出錯:%@,%@",error,[error userInfo]);
}
- 查詢實體
查詢實體的步驟如下:
首先創建NSFetchRequest
對象。然后通過NSEntityDescription
對象設置NSFetchRequest
對象將要抓取的實體。如果需要對抓取結果進行篩選,則需要通過NSPredicate
對象設置篩選條件。如果需要對結果進行排序,還需要為NSFetchRequest
添加多個NSSortDescriptor
對象。再調用NSManagedObjectContext
對象的executeFetchRequest:error:
方法執行查詢,該查詢方法將會返回所有符合條件的實體組成的NSArray
集合。如下代碼:
// 創建抓取數據的請求對象
NSFetchRequest *request = [[NSFetchRequest alloc] init];
// 設置要抓取哪種類型的實體
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Bison"
inManagedObjectContext:self.appDelegate.managedObjectContext];
// 設置抓取實體
[request setEntity:entity];
NSError *error = nil;
// 執行抓取數據的請求,返回符合條件的數據
eventArray = [[self.appDelegate.managedObjectContext
executeFetchRequest:request error:&error] mutableCopy];
基本的方法到此就結束了,具體的詳情可以下載Demo查看
下載地址
好文推薦:仿window阿里旺旺登陸界面,打印機吐紙動畫效果
原文地址:http://allluckly.cn
如對你有幫助,請不要吝惜你的star和喜歡哦!
技術交流群:534926022(免費) 511040024(0.8/人付費)
版權歸?Bison所有 如需轉載請保留原文超鏈接地址!否則后果自負!