iOS 10 以前创建CoreDataStack
1 Data Model
Data Model 是Xcode提供的一个可视化Model 编辑器,可以创建实例,定义实例属性,定义实例之间的关系,以及创建一些常用的FetchRequst
1.1 新建DataModel 文件
1.2 添加实例&定义属性
1.21 属性类型(Attribute Type)
- Integer16 Integer32 Integer64
- Decimal Float Double
- String
- Boolean
- Date
- Binary Data
- Transformable
其中,Binary Data
为二进制数据,在Xcode右侧Model Inspector 中,有一个可以设置Allows External Storage
的选项,CoreData会智能选择是存储文件的二进制数据,还是存储文件URL
Transformable
可以为任意遵循NSCoding
协议的对象类型
1.3 添加关系(relationShip)
- to one (一对一)
- to Manay (一对多)
这里再定义一个实例,主人(master),设定主人和狗子的关系为一对多,关系图如下:
2 CoreDataStack
CoreDataStck,是自定义的一个CoreData 的栈对象,为一个单例,可以通过它,初始化项目的CoreData,以及获取到Context,对数据库进行增删改查等操作
2.1 单例
// CoreDataStack.h
#import
#import
@interface CoreDataStack : NSObject
+ (instancetype)sharedInstance;
@end
// CoreDataStack.m
#import "CoreDataStack.h"
@implementation CoreDataStack
+ (instancetype)sharedInstance {
static CoreDataStack *stack;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
stack = [[CoreDataStack alloc] init];
});
return stack;
}
@end
3 NSManagedModel
The NSManagedObjectModel represents each object type in your app's data model, the properties they can have, and the relationship between them.
// CoreDataStack.m
@interface CoreDataStack ()
@property (nonatomic, strong) NSManagedObjectModel *managedModel;
@end
......
- (NSManagedObjectModel *)managedModel {
if (!_managedModel) {
NSURL *momdURL = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];
_managedModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momdURL];
}
return _managedModel;
}
NSManagedObjectModel
通过Xcode创建的DataModel
文件初始化,DataModel文件编译后的后缀为momd
。
4 NSPersistentStoreCoordinator
4.1 NSpersistentStore
atomic vs nonatomic
An atomic persistent store needs to be completely deserialized and loaded into memory before you can make any read or write operations. In contrast, a non- atomic persistent store can load chunks of itself onto memory as needed.
type
- NSSQLiteStoreType (nonatomic)
- NSXMLStoreType (atomic)
- NSBinaryStoreType (atomic)
- NSInMemoryStoreType (atomic)
4.2 NSPersistentStoreCoordinator
the bridge between the managed object model and the persistent store
- 通过
managed object model
初始化 - 通过
addPersistentStoreWithType:configuration:URL:options:error:
添加persistent store
// CoreDataStack.m
@interface CoreDataStack ()
@property (nonatomic, strong) NSPersistentStoreCoordinator *psc;
@end
......
- (NSPersistentStoreCoordinator *)psc {
if (!_psc) {
_psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedModel];
NSURL *URL = [[self documentURL] URLByAppendingPathComponent:@"Model.sqlite"];
NSError *error;
if (![_psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:URL options:nil error:&error]) {
NSLog(@"addPersistentStoreWithType Error: %@",[error localizedDescription]);
}
}
return _psc;
}
- (NSURL *)documentURL {
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
}
5 NSManagedObjectContext
Context是唯一暴露给外界,供外界使用的接口
- context an in-memory scratchpad for managed objects.
- any change you make won't affect the underlying data on disk until you call
-save:
of context- context manages the lifecycle of the objects that it creates or fetches.
- A managed object cannot exist without an associated context.
- once a managed object has associated with a particular context, it will remain associated with the same context for the duration of its lifecycle.
- context and managed object is not thread safe
// CoreDataStack.h
@interface CoreDataStack : NSObject
@property (nonatomic, strong, readonly) NSManagedObjectContext *managedContext;
@end
// CoreDataStack.m
@interface CoreDataStack ()
@property (nonatomic, strong, readwrite) NSManagedObjectContext *managedContext;
@end
- (NSManagedObjectContext *)managedContext {
if (!_managedContext) {
_managedContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedContext.persistentStoreCoordinator = self.psc;
}
return _managedContext;
}
6 Save Context
- (void)saveContext {
NSError *error;
if ([self.managedContext hasChanges] && ![self.managedContext save:&error]) {
NSLog(@"NSManagedObjectContext Save Error: %@",[error localizedDescription]);
}
}
iOS 10 以后创建CoreDataStack
iOS 10 以后,苹果系统为我们封装了一个CoreData Stack 的类,叫NSPersistentContainer
,可以通过它的属性viewContext
获取到NSManagedObjectContext
@property (readonly, strong) NSPersistentContainer *persistentContainer;
- (NSPersistentContainer *)persistentContainer {
// The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
@synchronized (self) {
if (_persistentContainer == nil) {
_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"testCoreData"];
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (error != nil) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
abort();
}
}];
}
}
return _persistentContainer;
}
- (void)saveContext {
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
abort();
}
}
源码下载
https://github.com/mengtian-li/CoreDataStackDemo/releases/tag/v0.1