core-data Objective-C示例

示例

这是用于iOS 10+的简单但功能强大的核心数据设置。有两种访问核心数据的方法:

  1. viewContext。将viewContext只能从主线程,并且仅被用于读取。

  2. 强大的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;
}