@簡單的說,Core Data就是可以存儲到磁盤的對象圖,[...]Core Data可以幫我們做很多任務作.它可以作為軟件的整個模型層。它不僅僅在磁盤上存儲數據,也把我們需要的數據對象讀取到內存中。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ——Marcus Zarra, Core Data
@Core Data是Mac OS X中Cocoa API的一部分,首次在Mac OS X 10.4 Tiger與iOS 3.0系統中出現[2]。它允許按照實體-屬性-值模型組織數據,并以XML,二進制文件或SQLite數據文件的格式將其串行化。Core Data允許用戶使用代表實體和實體間關系的高層對象來操作數據。它也可以管理串行化的數據,提供對象生存期管理與object graph管理,包括存儲。Core Data直接與SQLite交互,避免開發者使用原本的SQL語句,就像Cocoa綁定在模型-視圖-控制器設計中做了很多控制器的工作一樣,Core Data做了很多數據模型的工作。它的主要任務是負責數據更改的管理,串行化到磁盤,最小化內存占用,以及查詢數據。
@http://www.cocoachina.com/iphonedev/sdk/2010/1126/2397.html( 這是官方對于CoreData的說明)
@接下來,我就不利用框架自動生成代碼,完全自己編寫所有的 Core data 相關代碼的命令行應用程序來深入講解 Core data的使用。
***概念圖***

@添加CoreData框架,導入#import
寫代碼之前需要了解6個對象:
(1)NSManagedObjectContext(被管理的數據上下文)
操作實際內容(操作持久層)
作用:插入數據,查詢數據,刪除數據
(2)NSManagedObjectModel(被管理的數據模型)
數據庫所有表格或數據結構,包含各實體的定義信息
作用:添加實體的屬性,建立屬性之間的關系
操作方法:視圖編輯器,或代碼
(3)NSPersistentStoreCoordinator(持久化存儲助理)
相當于數據庫的連接器
作用:設置數據存儲的名字,位置,存儲方式,和存儲時機
(4)NSManagedObject(被管理的數據記錄)
相當于數據庫中的表格記錄
(5)NSFetchRequest(獲取數據的請求)
相當于查詢語句
(6)NSEntityDescription(實體結構)
相當于表格結構
(7)后綴為.xcdatamodeld的包
里面是.xcdatamodel文件,用數據模型編輯器編輯
編譯后為.momd或.mom文件
1.自定義封裝的CoreData管理類**HMTCoreDataManager**
**.h**
~~~
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
/**
* 數據存儲成功的代碼塊
*/
typedef void(^HandleSaveSuccessedBlock)();
/**
* 數據存儲失敗的代碼塊
*/
typedef void(^HandleSaveFailedBlock)(NSError *);
@interface HMTCoreDataManager : NSObject
@property (nonatomic,strong)NSManagedObjectContext *managedObjectContext; // 托管對象上下文
/**
* 創建一個單例對象
*
* @return 單例對象
*/
+ (HMTCoreDataManager *)defaultManager;
/**
* 根據實體描述獲得托管對象
*
* @param entityName 指定實體描述名字
* @param aClass 要獲取的托管對象
*
* @return 托管對象實例
*/
- (NSManagedObject *)managedObjectWithEntityName:(NSString *)entityName managedObjectClass:(Class)aClass;
/**
* 數據存儲到磁盤中成功和失敗響應的方法,參數為2個block
*
* @param aSuccessedHandler
* @param aFailedHandler
*/
- (void)saveWithSuccessedHandler:(HandleSaveSuccessedBlock)aSuccessedHandler failedHandler:(HandleSaveFailedBlock)aFailedHandler;
// 插入數據
- (void)insertCoreData;
// 查詢
- (NSMutableArray*)selectData:(NSString *)name;
// 刪除
- (void)deleteData:(NSManagedObject *)object;
// 更新
- (void)updateData:(NSString* )newName;
@end
~~~
.m
~~~
#import "HMTCoreDataManager.h"
@interface HMTCoreDataManager ()
@property (nonatomic,strong) NSPersistentStoreCoordinator *persistentStoreCoordinator; // 持久化存儲協調器
@property (nonatomic,strong) NSManagedObjectModel * managedObjectModel; // 托管對象模型
@end
@implementation HMTCoreDataManager
static HMTCoreDataManager *manager = nil;
+ (HMTCoreDataManager *)defaultManager{
@synchronized(self){
if (manager == nil) {
manager = [[HMTCoreDataManager alloc] init];
}
}
/*
// 通過GCD創建
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
manager = [[HMTCoreDataManager alloc] init];
});
*/
return manager;
}
#pragma mark - 屬性的方便之處能在get方法中初始化
/**
* 很多人對于這個上下文不太理解,開始我也不太理解,查了很多資料,感覺下面這個解釋比較通俗易懂
* 托管對象上下文:
* 托管對象上下文包含所有的托管對象,這些托管對象已經為提交給數據庫準備就緒,在托管對象上下文中,可以添加、修改和刪除托管對象,
* 這一層相當于應用程序和數據庫之間的緩沖區。
*/
- (NSManagedObjectContext *)managedObjectContext{
if (_managedObjectContext) {
return _managedObjectContext;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
// 為托管對象上下文指定一個持久化存儲協調器
[_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
return _managedObjectContext;
}
/**
* 持久化存儲協調器(持久化存儲助理)
* 持久化存儲協調器處理到數據存儲的連接,并且包含一些底層信息,像用到數據存儲的名字和位置
* 一般我們無需與它直接打交道,上下文已經封裝了對它的調用
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if (_persistentStoreCoordinator) {
return _persistentStoreCoordinator;
}
// 初始化一個持久化存儲協調器必須依賴NSManagedObjectModel
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
// 存儲路徑(返回的是NSURL類型)為Documents目錄下,以及數據庫名稱
NSURL *documentURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *fileURL = [documentURL URLByAppendingPathComponent:@"myClass.sqlite"];
NSError *error = nil;
// 加載持久化存儲數據(指定持久化存儲的數據類型,默認的是NSSQLiteStoreType,即SQLite數據庫)
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:fileURL options:nil error:&error];
if (error != nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"添加持久化存儲失敗" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alert show];
}
return _persistentStoreCoordinator;
}
/**
* 托管對象模型
* 數據庫所有表格或數據結構包含各實體的定義信息
* 添加實體的屬性,建立屬性之間的關系
*/
- (NSManagedObjectModel *)managedObjectModel{
if (_managedObjectModel) {
return _managedObjectModel;
}
// 獲取托管對象模型文件的地址
// 編譯器會自動將"xcdatamodeld"格式轉化為"momd"
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"myClassModel" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSManagedObject *)managedObjectWithEntityName:(NSString *)entityName managedObjectClass:(Class)aClass{
// 創建"HMTClass"的實體描述
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"HMTClassEntity" inManagedObjectContext:self.managedObjectContext];
// 通過"HMTClass"的實體描述創建HMTClass的托管對象
NSManagedObject *managedObject = [[aClass alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];
return managedObject;
}
- (void)saveWithSuccessedHandler:(HandleSaveSuccessedBlock)aSuccessedHandler failedHandler:(HandleSaveFailedBlock)aFailedHandler{
NSError *error = nil;
[self.managedObjectContext save:&error];
if (error != nil) {
aFailedHandler(error);
}else {
aSuccessedHandler();
}
}
@end
~~~
2.創建模型文件**ManagedObject****的過程**
**
**


3.將創建的模型文件轉化為對應的類文件
第一種:command+n

第二種: 選中myClassModel.xcdatamodeld
之后都是一樣的--->選中模型文件--->選中要創建的實體

最后,就會生成前面圖片中的3個類,都是繼承了NSManagedObject
~~~
------------------class-------------------------------
@class HMTStudent, HMTTeacher;
@interface HMTClass : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *students;
@property (nonatomic, retain) HMTTeacher *teacher;
@end
@interface HMTClass (CoreDataGeneratedAccessors)
- (void)addStudentsObject:(HMTStudent *)value;
- (void)removeStudentsObject:(HMTStudent *)value;
- (void)addStudents:(NSSet *)values;
- (void)removeStudents:(NSSet *)values;
@end
#import "HMTClass.h"
#import "HMTStudent.h"
#import "HMTTeacher.h"
@implementation HMTClass
@dynamic name;
@dynamic students;
@dynamic teacher;
@end
------------------teacher-------------------------------
@class HMTClass;
@interface HMTTeacher : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * course;
@property (nonatomic, retain) HMTClass *myClass;
@end
#import "HMTTeacher.h"
#import "HMTClass.h"
@implementation HMTTeacher
@dynamic name;
@dynamic course;
@dynamic myClass;
@end
------------------student-------------------------------
@class HMTClass, HMTTeacher;
@interface HMTStudent : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) HMTTeacher *teacher;
@property (nonatomic, retain) HMTClass *myClass;
@end
#import "HMTStudent.h"
#import "HMTClass.h"
#import "HMTTeacher.h"
@implementation HMTStudent
@dynamic name;
@dynamic age;
@dynamic teacher;
@dynamic myClass;
@end
~~~
4.準備工作都OK了,最后進行數據的持久化存儲
~~~
#pragma mark - 增刪改查
// 插入數據操作(類似于FMDB做法,方法后面可帶你想存儲的數據對象,這里只是單純的演示)
// - (void)insertCoreData:(AppleClass *)appleClass
- (void)insertCoreData{
// 創建"HMTClass"的實體描述,傳入的正是前面標注的實體描述名
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"HMTClassEntity" inManagedObjectContext:self.managedObjectContext];
// 通過"HMTClass"的實體描述創建HMTClass的托管對象
HMTClass *hmtClass = [[HMTClass alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];
// hmtClass.name = appleClass.name;
hmtClass.name = @"Apple";
// 托管對象上下文將托管對象的更改保存到磁盤文件中
// - save 將數據保存到數據庫
NSError *error = nil;
[self.managedObjectContext save:&error];
if (error != nil) {
NSLog(@"添加失敗:%@",[error localizedDescription]);
}
}
// 刪除數據操作
- (void)deleteData:(NSManagedObject *)object{
[self.managedObjectContext deleteObject:object];
NSError *error = nil;
[[HMTCoreDataManager defaultManager].managedObjectContext save:&error];
if (error != nil) {
NSLog(@"刪除失敗:%@",[error localizedDescription]);
}
}
// 查詢數據操作(依據特定條件查詢,如果是select * 就直接不寫謂詞判斷語句)
- (NSMutableArray*)selectData:(NSString *)name{
// 創建指定Entity的查詢語句
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"HMTClassEntity"];
// 謂詞,原理和用法都類似于SQL中的where,作用相當于數據庫的過濾取(我blog中OC分類有具體講到)
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name == \'%@\'",name],nil];
fetchRequest.predicate = predicate;
// 查詢的結果按哪個key進行排序,YES為升序
// NSSortDescriptor *timestampSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"classNO" ascending:YES];
// fetchRequest.sortDescriptors = @[timestampSortDescriptor];
// 注意查詢返回的只能是NSArray類型
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
NSMutableArray *resultArray = [NSMutableArray arrayWithArray:fetchedObjects];
return resultArray;
}
// 更新數據操作
- (void)updateData:(NSString *)newName{
// 創建指定Entity的查詢語句
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"HMTClassEntity"];
// 注意查詢返回的只能是NSArray類型
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
// 更新
for (HMTClass *info in fetchedObjects) {
info.name = newName;
}
//保存
if ([self.managedObjectContext save:nil]) {
//更新成功
NSLog(@"更新成功");
}
}
~~~
- 前言
- 沙盒機制與文件(一)
- 沙盒機制和文件(二)
- 沙盒機制和文件(三)
- NSBundle介紹以及讀取沙盒文件路徑問題
- 數據持久化(一)-----歸檔 讀寫 文件路徑
- 數據持久化(二)-----Sqlite
- 數據持久化(三)使用第三方類庫FMDB
- 數據持久化(四)之NSUserDefaults
- 數據持久化(五)之CoreData
- 數據持久化(六)之Using CoreData with MagicalRecord
- 數據解析(一)解析XML之系統自帶NSXMLParse類
- 數據解析(二)解析XML之GDataXMLNode
- 數據解析(三)解析JSON-----系統自帶NSJSONSerialization 與 第三方JSONKit
- iOS多線程編程(一)NSThread
- iOS多線程編程(二)NSOperationQueue
- iOS多線程編程(三)Grand Central Dispatch(GCD)詳解
- iOS網絡編程(一)NSURLConnection
- iOS網絡編程(二) 自定義請求網絡類----推薦用于需要請求過程片段數據
- iOS網絡編程(三) 異步加載及緩存圖片---->SDWebImage
- iOS網絡編程(四) 異步加載及緩存圖片-----自定義類
- iOS網絡編程(五) 異步加載及緩存圖片-----EGO
- iOS網絡編程(六) NSURLSession詳解
- iOS網絡編程(7) 第三方開源庫----->AFNetworking