iOS-CoreData詳解與使用


上面已經說完了SQLite和FMDB以及兩者的區別,本篇將講述iOS中另一個存儲方式,CoreData的使用。通讀下來大約10分鍾,后續還會根據項目中問題,不斷更新。

 

一、預備知識

在了解CoreData,大家有必要了解對象關系映射(英語稱object Relational Mapping,簡稱ORM)。

1.ORM

ORM是通過使用描述對象和數據庫之間映射的元數據,可以實現將對象自動持久化到關系數據庫當中。ORM的存在為了解決面向對象與數據庫科恩干存在不匹配的一種技術。

 

二、初識CoreData

1.CoreData是一種在iOS 3系統中,也是蘋果自己推出的數據存儲框架,采用了一種ORM(對象關系映射)的存儲關系。CoreData一個比較大的優勢在於在使用CoreData過程中不需要我們編寫SQL語句,也就是將OC對象存儲於數據庫,也可以將數據庫數據轉為OC對象(數據庫數據與OC對象相互轉換)。

 

2.CoreData幾個類

(1)NSManagedObjectContext

意思是托管對象上下文,數據庫的大多數操作是在這個類操作

(2)NSManagedObjectModel

意思是托管對象模型,其中一個托管對象模型關聯到一個模型文件,里面存儲着數據庫的數據結構。

(3)NSPersistentStoreCoordinator

意思是持久化存儲協調器,主要負責協調上下文玉存儲的區域的關系。

(4)NSManagedObject

意思是托管對象類,其中CoreData里面的托管對象都會繼承此類。

 

三、CoreData基本使用

 下面開始講解CoreData的基本使用,里面會插入圖片和代碼,可能內容比較多,希望大家靜下來看完(比較考驗大家的耐心程度)。

使用CoreData方式,有兩種可能。第一種是項目開始就創建帶有CoreData數據庫,還有一種項目已經開始了,重新接入CoreData,下面我們第三部分主要講述這兩種方式的過程。

1.項目開始就使用CoreData

我們在創建項目的時候,勾選Use Core Data

如果利用項目剛建時,勾選Use Core Data,這樣在目錄中就會出現,后綴名為.xcdatamodeld。

打開AppDelegate發現類中多了以下內容

AppDelegate.h

 

AppDelegate.m中

我們可以點開testCoreData.xcdatamodeld文件,我們可以看到實體和關系。如下圖

通過點擊左色紅色添加紅色,右邊紅色添加屬性,在這中間我們還需要留意一些細節。

(1)

創建后可以清楚的看到模型文件左側的列表,有三個Entities、Fetch Requests以及Configurations三個選項,意思分別是:實體,請求模版以及配置信息。

(2)

添加完一個實體后,你會發現一個實體是對應着三個內容,分別是Attributes、Relationships和Fetched Properties,意思分別是:屬性、關聯關系以及獲取操作。

(3)實體屬性類型

我們來分別簡單解釋類型的意義,從上往下

Undefined:也就是默認值,如果參與編譯會報錯

Integer 16:代表整數,范圍是-32768 ~ 32767

Integer 32:代表整數,范圍是-2147483648 ~ 2147483647

Integer 64:代表整數,范圍是–9223372036854775808 ~ 9223372036854775807,還是很大的,較少用

Double:代表小數

Float:代表小數

String:代表字符串,NSString表示

Boolean:代表布爾值,使用NSNumber表示

Date:代表日期時期

Binary Data:代表二進制,是用NSData表示

Transformable:代表Objective對象,要遵守NSCoding協議

(4)關聯關系

 

點擊加號,可以添加關聯關系,在inverse這個屬性代表兩個實體在Relationships設置關聯關系后之后,是否可以從一個實體中找到另一個實體,這樣使兩個實體具有雙向的關聯關系。

(5)Editor Style

大家通過點擊下面紅色按鈕,style按鈕可以看出實體和屬性的關系,以及可以看出實體之間的對應的關系。

上面是coreData的視圖的基本運用,自己也是一個不斷摸索的過程,下面講述CoreData的基本操作。

 

三、CoreData基本使用

在講述操作之前,我們首先講述NSManagedObjectContext,蘋果推薦使用initWithConcurrencyType方式創建,在創建時,指定當前是什么類型的並發隊列,參數也是一個枚舉值。

NSManagedObjectContext枚舉值參數有三個類型:

(1)NSConfinementConcurrencyType:此類型在iOS9之后被蘋果棄用,所以不建議用這個API。

(2)NSPrivateQueueConcurrencyType:代表私有並發隊列的類型,操作也是在子線程中完成的。

(3)NSMainQueueConcurrencyType:代表主並發隊列類型,如果在操作過程中,需要涉及到UI操作,則應該使用這個參數初始化上下文完成操作。

下面我們一個company的模型文件-主隊列並發類型的NSManagedObjectContext

// 創建上下文對象,並發隊列設置為主隊列
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

// 創建托管對象模型,並使用Company.momd路徑當做初始化參數
NSURL *modelPath = [[NSBundle mainBundle] URLForResource:@"Company" withExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelPath];

// 創建持久化存儲調度器
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

// 創建並關聯SQLite數據庫文件,如果已經存在則不會重復創建
NSString *dataPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
dataPath = [dataPath stringByAppendingFormat:@"/%@.sqlite", @"Company"];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:dataPath] options:nil error:nil];

// 上下文對象設置屬性為持久化存儲器
context.persistentStoreCoordinator = coordinator;

 

3.1 插入操作

CoreData通過NSEntityDescription的insert進行插入操作,這樣就會生成並返回一個托管對象,並將這個對象插入到上下文中。下面以一個Employee為例:

// 開始創建托管對象,並指明好創建的托管對象所屬實體名
Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:context];
emp.name = @"lxz";
emp.height = @1.7;
emp.brithday = [NSDate date];

// 通過這樣上下文保存對象,並在保存前判斷是否有了最新的更改
NSError *error = nil;
if (context.hasChanges) {
    [context save:&error];
}

// 錯誤處理
if (error) {
    NSLog(@"CoreData Insert Data Error : %@", error);
}

NSManagedObjectContext將操作的數據放到了緩存層中,只有調用了NSManagedObjectContext的save后,才會對數據庫進行真正的操作,否則對象僅僅存在內存中,這樣就很好地避免了數據庫的頻繁訪問。

 

3.2 刪除操作

CoreData首先通過獲取需要刪除的托管對象,遍歷所需要獲取的對象數組,逐個刪除,最后調用NSManagedObjectContext的save方法。

// 獲取數據的請求對象,指明對實體進行刪除操作,以Employee為例
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];

// 通過創建謂詞對象,然后過濾掉符合要求的對象,也就是要刪除的對象
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"lxz"];
request.predicate = predicate;

// 通過執行獲取操作,找到要刪除的對象即可
NSError *error = nil;
NSArray<Employee *> *employees = [context executeFetchRequest:request error:&error];

// 開始真正操作,一一遍歷,遍歷符合刪除要求的對象數組,執行刪除操作
[employees enumerateObjectsUsingBlock:^(Employee * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [context deleteObject:obj];
}];

// 最后保存數據,保存上下文。
if (context.hasChanges) {
    [context save:nil];
}

// 錯誤處理
if (error) {
    NSLog(@"CoreData Delete Data Error : %@", error);
}

 

3.3 修改操作

具體的描述和上面差不多。

// 獲取數據的請求對象,指明對實體進行修改操作,以Employee為例
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];

// 創建謂詞對象,設置過濾條件,找到要修改的對象
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"lxz"];
request.predicate = predicate;

// 通過執行獲取請求,獲取到符合要求的托管對象,修改即可
NSError *error = nil;
NSArray<Employee *> *employees = [context executeFetchRequest:request error:&error];
[employees enumerateObjectsUsingBlock:^(Employee * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    obj.height = @3.f;
}];

// 通過調用save將上面的修改進行存儲
if (context.hasChanges) {
    [context save:nil];
}

// 錯誤處理
if (error) {
    NSLog(@"CoreData Update Data Error : %@", error);
}

 

3.4 查找操作

查找操作是是有許多條件限制,根據條件查找出相應的數據,下面以一個例子說明一下(查找出所有的元素,條件以后細節會講出)

//  獲取數據的請求對象,指明對實體進行查詢操作,以Employee為例
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];

// 執行獲取操作,獲取所有Employee托管對象
NSError *error = nil;
NSArray<Employee *> *employees = [context executeFetchRequest:request error:&error];
[employees enumerateObjectsUsingBlock:^(Employee * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"Employee Name : %@, Height : %@, Brithday : %@", obj.name, obj.height, obj.brithday);
}];

// 錯誤處理
if (error) {
    NSLog(@"CoreData Ergodic Data Error : %@", error);
}

以上就是CoreData的基本使用,自己也在不斷的完善中,希望上面對大家對CoreData認識會進一步提高。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM