这是用于iOS 10+的简单但功能强大的核心数据设置。有两种访问核心数据的方法:
viewContext。将viewContext只能从主线程,并且仅被用于读取。
强大的enqueueCoreDataBlock。所有写作都应使用完成enqueueCoreDataBlock。最后无需保存,它将自动保存。所有写入都排队在operationQueue中,因此永远不会发生写入冲突。
确保切勿在另一个上下文中使用上下文中的任何ManagedObjects。还要丢弃所有创建或获取的对象,enqueueCoreDataBlock因为执行该块后,支持它们的上下文将被破坏。
// CoreDataManager.h
@interface CoreDataManager : NSObject @property (nonatomic, readonly) NSManagedObjectContext * viewContext; - (void)enqueueCoreDataBlock:(void (^)(NSManagedObjectContext* context))block; @end
// CoreDataManager.m
@implementation NSManagedObjectContext(SaveIfNeeded)
-(BOOL) saveIfNeeded{
BOOL toReturn = YES;
if ([self hasChanges]) {
NSError *error;
toReturn = [self save:&error];
if (toReturn == NO || error)
{
//在这里您应该登录到您的分析服务
NSLog(@"--- Failed to commit data\n error: %@", error);
}
}
return toReturn;
}
@end
@interface CoreDataManager ()
@property (nonatomic, strong) NSPersistentContainer* persistentContainer;
@property (nonatomic, strong) NSOperationQueue* persistentContainerQueue;
@end
@implementation CoreDataManager
- (id)init
{
self = [super init]
if (self)
{
self.persistentContainer= [[NSPersistentContainer alloc] initWithName:@"PROJECT_NAME_ALSO_NAME_OF_MODEL" managedObjectModel:managedObjectModel];
[self.persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription * description, NSError * error) {
}];
self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;
_persistentContainerQueue = [[NSOperationQueue alloc] init];
_persistentContainerQueue.maxConcurrentOperationCount = 1;
_persistentContainerQueue.name = @"persistentContainerQueue";
dispatch_queue_t queue = dispatch_queue_create("persistentContainerQueue.dispatchQueue", DISPATCH_QUEUE_SERIAL);
_persistentContainerQueue.underlyingQueue = queue;
}
}
- (void)enqueueCoreDataBlock:(void (^)(NSManagedObjectContext* context))block{
void (^blockCopy)(NSManagedObjectContext*) = [block copy];
[self.persistentContainerQueue addOperation:[NSBlockOperation blockOperationWithBlock:^{
NSManagedObjectContext* context = self.persistentContainer.newBackgroundContext;
[context performBlockAndWait:^{
blockCopy(context);
[context saveIfNeeded];
}];
}]];
}
-(NSManagedObjectContext*) viewContext{
if (![NSThread mainThread]) {
//在这里您应该登录到您的分析服务。如果您处于开发人员模式,则应崩溃以强制您解决此问题
NSLog(@"在错误的线程上访问上下文!");
}
return self.persistentContainer.viewContext;
}