Core Data的一些常見用法,coredata用法
一、簡介
Core Data是一個純粹的物件導向架構,其本質就是一個ORM(對象關係映射:Object Relational Mapping),能以物件導向的方式操作SQLite資料庫。在實際開發中絕大部分情況下,Core Data底層都採用SQLite資料庫作為持久化儲存方式。它也允許把資料儲存在記憶體中(裝置重啟後資料會丟失),也允許把資料存放區為其他格式(如XML)。簡單的講,它就是用於操作實體以及實體之間的關聯關係的持久化工具。
二、Core Data的核心概念。
1、實體
實體就是由Core Data管理的模型對象,是NSManagedObject類或其子類的執行個體。
實體與實體之間是1-1、1-N、N-N的關聯關係。
2、實體描述
NSEntityDescription:該對象描述了實體的具體資訊(如包含的所有屬性等),相當於實體的抽象。
3、託管物件模型
NSManagedObjectModel:該對象負責管理所有實體以及實體之間的關聯關係。
4、託管物件內容
NSManagedObjectContext:簡稱上下文,所有實體都處於內容相關的管理中,實體的增、刪、改、查操作都必須通過該對象來完成。類似於Hibernate的Session。
5、持久化儲存協調器
NSPersistentStoreCoordinator:底層與NSManagedObjectContext相銜接,負責管理底層的儲存形式(如SQLite資料庫或XML等)。
6、抓取請求
NSRetchRequest:該對象封裝了查詢實體的請求,例如需要查詢哪些實體、查詢條件(通過NSPredicate來表示)、定序(用NSArray定義了所有的定序)等。
三、使用Core Data的步驟。
註:建立項目時如果勾選"Use Core Data"複選框,Xcode會自動完成所有Core Data必需資源的初始化,前3步會自動完成,此時需從第4步開始操作。
1、為項目匯入CoreData.Framework架構。
2、添加實體模型檔案。
Xcode → File → New → File → Data Model → next → "實體模型檔案名稱".xcdatamodeld → create;
3、初始化Core Data必需的核心API對象,這些是屬於全域對象,一般會在AppDelegate中操作。
(1)、在AppDelegate.h中添加3個核心屬性,再添加一個執行儲存的方法。
1 #import <UIKit/UIKit.h> 2 #import <CoreData/CoreData.h> 3 4 @interface AppDelegate : UIResponder <UIApplicationDelegate> 5 6 @property (strong, nonatomic) UIWindow *window; 7 8 @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext; 9 @property (nonatomic, strong) NSManagedObjectModel *managedObjectModel;10 @property (nonatomic, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator;11 12 - (void)saveContext;13 14 @end
(2)、在AppDelegate.m中初始化NSManagedObjectModel。
1 - (NSManagedObjectModel *)managedObjectModel {3 if (_managedObjectModel != nil) {4 return _managedObjectModel;5 }6 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData2" withExtension:@"momd"];7 _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];8 return _managedObjectModel;9 }
(3)、以NSManagedObjectModel對象為基礎,在AppDelegate.m中初始化NSPersistentStoreCoordinator,用於設定Core Data底層資料存放區方式。
1 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 2 if (_persistentStoreCoordinator != nil) { 3 return _persistentStoreCoordinator; 4 } 5 _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 6 NSURL *storeURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 7 storeURL = [storeURL URLByAppendingPathComponent:@"CoreData2.sqlite"]; 8 NSError *error = nil; 9 if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {10 NSLog(@"Unresolved error %@, %@", error, [error userInfo]);11 abort();12 }13 14 return _persistentStoreCoordinator;15 }
(4)、以NSManagedObjectModel對象為基礎,在AppDelegate.m中初始化NSManagedObjectContext。
1 - (NSManagedObjectContext *)managedObjectContext { 2 if (_managedObjectContext != nil) { 3 return _managedObjectContext; 4 } 5 6 NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 7 if (!coordinator) { 8 return nil; 9 }10 _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];11 [_managedObjectContext setPersistentStoreCoordinator:coordinator];12 return _managedObjectContext;13 }
(5)、在AppDelegate.m中實現saveContext方法,用於儲存資料。
1 - (void)saveContext { 2 NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 3 if (managedObjectContext != nil) { 4 NSError *error = nil; 5 if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 6 NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 7 abort(); 8 } 9 }10 }
(6)、在AppDelegate.m中實現此方法,當應用在後台被終止時,儲存上下文中的資料。
1 - (void)applicationWillTerminate:(UIApplication *)application {2 [self saveContext];3 }
經過以上3大步驟,Core Data項目初始化完成,當應用程式需要執行增、刪、改、查等操作時,直接調用AppDelegate中的managedObjectContext屬性即可操作。
4、設計實體模型。
單擊Xcode項目導航中的"實體模型檔案名稱".xcdatamodeld檔案,開啟實體模型開始編輯。
(1)、實體:是實體模型的核心對象,實體必需是NSManagedObject類或其子類。點擊"Add Entity"添加實體。
(2)、抓取請求:是NSFetchRequest對象,實際開發中通常會在代碼中建立。
(3)、配置:系統預設配置,無需自行添加。
(4)、屬性:相當於實體物件的執行個體變數,在實體列表中選中剛產生的實體,點擊"Add Attribute"添加屬性。
(5)、關聯關係:定義實體之間的關聯關係,如1-1、1-N、N-N。具體操作如下:
選中實體 → 在Relationships下點擊加號添加關聯關係 → 在Relationship下填寫關聯關係名稱 → 在Destination下選擇目標實體 → 在Xcode屬性面板的Type中選擇關聯類別型 → 在Xcode屬性面板的Delete Rule中選擇級聯類型。
- Relationship:關聯關係的名稱。
- Destination:關聯關係的目標實體。
- Inverse:建立實體與目標實體之間的關聯關係,保持資料的完整性,不設定的話編譯器會有警告。
- Type中的To One:1-1.
- Type中的To Many:1-N。 // N-N的情況需設定其他的實體對此實體為1-N
- Delete Rule的No Action:當主實體被刪除時,關聯的目標實體不變。
- Delete Rule的Nullify:當主實體被刪除時,關聯的目標實體外索引值被設定為null。
- Delete Rule的Cascade:當主實體被刪除時,關聯的目標實體也被串聯刪除。
- Delete Rule的Deny:當主實體被刪除時,如果被關聯的目標實體還存在,程式會拒絕刪除主實體的操作。必需先刪除關聯的目標實體,才能刪除主實體。
(6)、抓取屬性:在擷取關聯實體時可執行某個過濾條件。
5、用實體模型產生實體。
即以"實體模型檔案名稱".xcdatamodeld檔案中的某個實體為基礎,為該實體產生NSManagedObject的子類。
Xcode → File → New → File → NSManagedObject Subclass → 選擇實體模型檔案 → 選擇檔案中的實體(大於1個時) → create;
6、實現資料的增、刪、改、查。
(1)、添加實體。
- 調用NSEntityDescription的insertNewObjectForEntityForName:inManagedObjectContext:類方法添加新實體。
- 調用NSManagedObjectContext對象的save方法儲存上下文。
1 HLAuthor *author = [NSEntityDescription insertNewObjectForEntityForName:@"HLAuthor" inManagedObjectContext:self.appDelegate.managedObjectContext];2 author.name = @"張三";3 author.authorDesc = @"xxx";4 NSError *error = nil;5 if (![self.appDelegate.managedObjectContext save:&error]) {6 NSLog(@"儲存失敗:%@, %@", error, error.userInfo);7 }
(2)、刪除實體。
- 擷取要刪除的實體。
- 調用NSManagedObjectContext對象的deleteObject:方法刪除實體。
- 調用NSManagedObjectContext對象的save方法儲存上下文。
1 HLAuthor *author = self.authorArray[indexPath.row];2 [self.appDelegate.managedObjectContext deleteObject:author];3 NSError *error = nil;4 if (![self.appDelegate.managedObjectContext save:&error]) {5 NSLog(@"刪除失敗:%@, %@", error, error.userInfo);6 }
(3)、修改實體。
- 擷取要修改的實體。
- 修改實體屬性。
- 調用NSManagedObjectContext對象的save方法儲存上下文。
1 HLAuthor *author = .....;2 author.name = .....;3 author.authorDesc = .....;4 NSError *error = nil;5 if ([self.delegate.managedObjectContext save:&error]) {6 NSLog(@"修改失敗:%@, %@", error, error.userInfo);7 }
(4)、查詢實體。
- 建立NSFetchRequest對象。
- 通過NSEntityDescription對象設定NSFetchRequest對象所要抓取的實體。
- 通過NSPredicate對象設定篩選條件(如果需要),通過NSSortDescriptor對象設定查詢結果的定序(如果需要)。
- 調用NSManagedObjectcontext對象的executeFetchRequest:error:方法執行查詢,返回所有合格結果集NSArray。
1 NSFetchRequest *request = [[NSFetchRequest alloc] init];2 NSEntityDescription *entity = [NSEntityDescription entityForName:@"author" inManagedObjectContext:self.appDelegate.managedObjectContext];3 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"nane = %@", @"張三"];4 NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];5 request.entity = entity;6 request.predicate = predicate;7 request.sortDescriptors = @[descriptor];8 NSError *error = nil;9 NSArray *result = [self.appDelegate.managedObjectContext executeFetchRequest:request error:&error];