你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> Core Data的使用

Core Data的使用

編輯:關於IOS

一、概念

1.Core Data 是數據持久化存儲的最佳方式

2.數據最終的存儲類型可以是:SQLite數據庫,XML,二進制,內存裡,或自定義數據類型

在Mac OS X 10.5Leopard及以後的版本中,開發者也可以通過繼承NSPersistentStore類以創建自定義的存儲格式

3.好處:能夠合理管理內存,避免使用sql的麻煩,高效

4.構成:

(1)NSManagedObjectContext(被管理的數據上下文)

操作實際內容(操作持久層)

作用:插入數據,查詢數據,刪除數據

(2)NSManagedObjectModel(被管理的數據模型)

數據庫所有表格或數據結構,包含各實體的定義信息

作用:添加實體的屬性,建立屬性之間的關系

操作方法:視圖編輯器,或代碼

(3)NSPersistentStoreCoordinator(持久化存儲助理)

相當於數據庫的連接器

作用:設置數據存儲的名字,位置,存儲方式,和存儲時機

(4)NSManagedObject(被管理的數據記錄)

相當於數據庫中的表格記錄

(5)NSFetchRequest(獲取數據的請求)

相當於查詢語句

(6)NSEntityDescription(實體結構)

相當於表格結構

(7)後綴為.xcdatamodeld的包

裡面是.xcdatamodel文件,用數據模型編輯器編輯

編譯後為.momd或.mom文件

5.依賴關系

Core Data的使用

 

 

二、基於SQLite數據庫時,Core Data的簡單使用

和SQLite的區別:只能取出整個實體記錄,然後分解,之後才能得到實體的某個屬性

1.構建流程

包括:創建數據上下文,創建數據模型,創建數據持久化存儲助理

(1)若是新建的工程,選擇空白應用程序,next

Core Data的使用

勾選Use Core Data選項

Core Data的使用

此時生成的工程文件AppDelegate中,會自動生成被管理的數據上下文等相關代碼

(2)比如AppDelegate.h文件中,自動生成

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

方法saveContext表示:保存數據到持久層(數據庫)

方法applicationDocumentsDirectory表示:應用程序沙箱下的Documents目錄路徑

(例如/var/mobile/Applications/5FG80A45-DFB5-4087-A1B1-41342A977E21/Documents/)

(3)比如AppDelegate.h文件中,自動生成

@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

保存數據到持久層

- (void)applicationWillTerminate:(UIApplication *)application
{
    [self saveContext];
}
Core Data的使用
- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }
}
Core Data的使用

Documents目錄路徑

- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

被管理的數據上下文

初始化的後,必須設置持久化存儲助理

Core Data的使用
- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil) {
        return __managedObjectContext;
    }
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}
Core Data的使用

 

被管理的數據模型

初始化必須依賴.momd文件路徑,而.momd文件由.xcdatamodeld文件編譯而來

Core Data的使用
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil) {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TestApp" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}
Core Data的使用

持久化存儲助理

初始化必須依賴NSManagedObjectModel,之後要指定持久化存儲的數據類型,默認的是NSSQLiteStoreType,即SQLite數據庫;並指定存儲路徑為Documents目錄下,以及數據庫名稱

Core Data的使用
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil) {
        return __persistentStoreCoordinator;
    }
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestApp.sqlite"];
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    return __persistentStoreCoordinator;
}
Core Data的使用

如果不是新工程,也可以自己寫入相關代碼

(4)此外還生成了TestApp.xcdatamodeld文件

(5)還自動鏈接了CoreData.framework

(6)在預編譯頭.pch文件中,加入導入了CoreData.h頭文件

#import <CoreData/CoreData.h>

 

2.創建數據模型(數據模型編輯器操作)

(1)創建實體

選中.xcodedatamodel對象

Core Data的使用

在右邊的數據模型編輯器的底部工具欄點擊Add Entity添加實體

Core Data的使用

在最右側欄對實體命名

Core Data的使用

(2)創建實體屬性

選中實體,點擊底部工具欄的Add Attribute添加屬性

Core Data的使用

選中新添加的屬性,對屬性進行命名,並設置屬性的數據類型Attribute Type

Core Data的使用

(3)為兩個實體建立關系

選中一個實體,在底部工具欄點擊Add Relationship添加關系

Core Data的使用

選中新關系,對關系添加名稱,目標destination設置為另個實體

Core Data的使用

(4)建立返回關系

(當你建立一個目標關系,最好建立一個返回關系)

在另一個實體中建立一個關系並命名,設置目標對象為這之前的實體

並在Inverse屬性選這之前的關系名稱

Core Data的使用

 

(5)設置兩個關系的刪除規則Delete Rule,都為關聯模式

關聯模式cascade:其中一個數據被刪除,另一個實體中的數據也會跟著刪除

Core Data的使用

(6)最終兩個對象的關系圖為

Core Data的使用

切換Editor Stype按鈕

Core Data的使用

會看到另一種編輯方式:

Core Data的使用

Core Data的使用

 3.插入數據

在AppDelegate.m的application:didFinishLaunchingWithOptions:方法裡,調用自定義方法

insertCoreData插入數據,代碼如下:

Core Data的使用
- (void)insertCoreData
{
    NSManagedObjectContext *context = [self managedObjectContext];
    
    NSManagedObject *contactInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactInfo" inManagedObjectContext:context];
    [contactInfo setValue:@"name B" forKey:@"name"];
    [contactInfo setValue:@"birthday B" forKey:@"birthday"];
    [contactInfo setValue:@"age B" forKey:@"age"];
    
    NSManagedObject *contactDetailInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactDetailInfo" inManagedObjectContext:context];
    [contactDetailInfo setValue:@"address B" forKey:@"address"];
    [contactDetailInfo setValue:@"name B" forKey:@"name"];
    [contactDetailInfo setValue:@"telephone B" forKey:@"telephone"];
    
    [contactDetailInfo setValue:contactInfo forKey:@"info"];
    [contactInfo setValue:contactDetailInfo forKey:@"details"];
    
    NSError *error;
    if(![context save:&error])
    {
        NSLog(@"不能保存:%@",[error localizedDescription]);
    }
}
Core Data的使用

創建數據上下文,調用insertNewObjectForName方法,創建兩個數據記錄NSManagedObject,然後就可以對之前數據模型編輯視圖中定義的屬性進行賦值。此時的數據只在內存中被修改,最後調用數據上下文的save方法,保存到持久層

4.查詢數據

在調用了insertCoreData之後,可以調用自定的查詢方法dataFetchRequest來查詢插入的數據

Core Data的使用
- (void)dataFetchRequest
{
    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSError *error;
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *info in fetchedObjects) {
        NSLog(@"name:%@", [info valueForKey:@"name"]);
        NSLog(@"age:%@", [info valueForKey:@"age"]);
        NSLog(@"birthday:%@", [info valueForKey:@"birthday"]);
        NSManagedObject *details = [info valueForKey:@"details"];
        NSLog(@"address:%@", [details valueForKey:@"address"]);
         NSLog(@"telephone:%@", [details valueForKey:@"telephone"]);
    }
}
Core Data的使用

fetchRequest相當於sql查詢語句的包裝類,需要用setEntity方法,來指定具體查詢的實體結構(表結構)

通過NSEntityDescription的entityForName方法來,返回指向該具體實體結構的指針

然後調用executeFetchRequest:error:方法,來執行查詢操作,如果操作成功,則返回對應的數據記錄數組

其中,可以通過NSManagedObject數據記錄對象裡關聯的屬性,查詢另一個數據記錄對象裡的屬性

5.數據模版

為每個實體生成一個NSManagedObject子類

上面設置數據和獲取數據時,使用的是Key-Value方式,更好的方法是通過生成強類型的NSManagedObject的子類,通過類的成員屬性來訪問和獲取數據

(1)在數據編輯器視圖中選中實體對象,

選則file菜單,點擊new,點擊file...,選擇Core Data項,選擇NSManagedObject subclass,生成該實體同名的類,

繼承於NSManagedObject

Core Data的使用

生成對應的ContactInfo.h文件

Core Data的使用
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class ContactDetailInfo;

@interface ContactInfo : NSManagedObject

@property (nonatomic, retain) NSString * age;
@property (nonatomic, retain) NSString * birthday;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) ContactDetailInfo *details;

@end
Core Data的使用

和ContactInfo.m文件

其中,@dynamic告訴編譯器不做處理,使編譯通過,其getter和setter方法會在運行時動態創建,由Core Data框架為此類屬性生成存取方法

Core Data的使用
#import "ContactInfo.h"
#import "ContactDetailInfo.h"


@implementation ContactInfo

@dynamic age;
@dynamic birthday;
@dynamic name;
@dynamic details;

@end
Core Data的使用

以及ContactDetailInfo.h文件

Core Data的使用
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class ContactInfo;

@interface ContactDetailInfo : NSManagedObject

@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * telephone;
@property (nonatomic, retain) ContactInfo *info;

@end
Core Data的使用

和ContactDetailInfo.m文件

Core Data的使用
#import "ContactDetailInfo.h"
#import "ContactInfo.h"


@implementation ContactDetailInfo

@dynamic address;
@dynamic name;
@dynamic telephone;
@dynamic info;

@end
Core Data的使用

此時,數據模型編輯器視圖最右邊欄中,實體的class就變成具體的類名

Core Data的使用

之前用Key-Value的代碼就可以修改為:

#import "ContactInfo.h"
#import "ContactDetailInfo.h"
Core Data的使用
- (void)insertCoreData
{
    NSManagedObjectContext *context = [self managedObjectContext];
    
    ContactInfo *contactInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactInfo" inManagedObjectContext:context];
    contactInfo.name = @"name B";
    contactInfo.birthday = @"birthday B";
    contactInfo.age = @"age B";
    
    ContactDetailInfo *contactDetailInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactDetailInfo" inManagedObjectContext:context];
    contactDetailInfo.address = @"address B";
    contactDetailInfo.name = @"name B";
    contactDetailInfo.telephone = @"telephone B";
    
    contactDetailInfo.info = contactInfo;
    contactInfo.details = contactDetailInfo;
    
    NSError *error;
    if(![context save:&error])
    {
        NSLog(@"不能保存:%@",[error localizedDescription]);
    }
}
Core Data的使用 Core Data的使用
- (void)dataFetchRequest
{
    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSError *error;
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    for (ContactInfo *info in fetchedObjects) {
        
        NSLog(@"name:%@", info.name);
        NSLog(@"age:%@", info.age);
        NSLog(@"birthday:%@", info.birthday);
        ContactDetailInfo *details = info.details;
        NSLog(@"address:%@", details.address);
         NSLog(@"telephone:%@", details.telephone);
    }
}
Core Data的使用

 

三、數據庫相關

1.打印隱藏的sql語句:

在Edit Scheme中選擇Run,之後進入Arguments標簽,添加參數:“-com.apple.CoreData.SQLDebug 1”

2.使用SQLite存儲時,數據庫結構

存儲的SQLite數據庫表名稱:大寫“Z”加上實體名稱大寫,一個實體相當於一張表

具體的字段名稱:大寫“Z”加上實體屬性名稱大寫

Core Data的使用

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved