【问题标题】:Issue CoreData Migration发布 CoreData 迁移
【发布时间】:2014-11-05 07:50:24
【问题描述】:

我有一个包含两个 sqlite 数据库和两个 xcdatamodel 的应用程序。所以一切都很好,除非我想为其中一个模型更改或添加一些属性。

我正在创建一个新的模型版本并对其进行更改。设置当前模型版本后,我启动我的应用程序并得到以下异常:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores.  It cannot perform a save operation.'

我的 CoreData 运营有以下经理:

@interface CoreDataManager ()

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

@property (strong, nonatomic) NSManagedObjectContext *mainQueueContext;
@property (strong, nonatomic) NSManagedObjectContext *privateQueueContext;

@end

@implementation CoreDataManager

+ (instancetype)defaultStore
{
static CoreDataManager *_defaultStore = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    _defaultStore = [self new];
});

return _defaultStore;
}

#pragma mark - Singleton Access

+ (NSManagedObjectContext *)mainQueueContextWithDB:(NSString *)db
{
return [[self defaultStore] mainQueueContextWithDB:db];
}

+ (NSManagedObjectContext *)privateQueueContextWithDB:(NSString *)db
{
return [[self defaultStore] privateQueueContextWithDB:db];
}

+ (NSManagedObjectID *)managedObjectIDFromString:(NSString *)managedObjectIDString
{
return [[[self defaultStore] persistentStoreCoordinator] managedObjectIDForURIRepresentation:[NSURL URLWithString:managedObjectIDString]];
}

#pragma mark - Lifecycle

- (id)init
{
self = [super init];
if (self) {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSavePrivateQueueContext:)name:NSManagedObjectContextDidSaveNotification object:[self privateQueueContext]];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSaveMainQueueContext:) name:NSManagedObjectContextDidSaveNotification object:[self mainQueueContext]];
}
return self;
}

- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Notifications

- (void)contextDidSavePrivateQueueContext:(NSNotification *)notification
{
@synchronized(self) {
    [self.mainQueueContext performBlock:^{
        [self.mainQueueContext mergeChangesFromContextDidSaveNotification:notification];
    }];
}
}

- (void)contextDidSaveMainQueueContext:(NSNotification *)notification
{
@synchronized(self) {
    [self.privateQueueContext performBlock:^{
        [self.privateQueueContext mergeChangesFromContextDidSaveNotification:notification];
    }];
}
}

#pragma mark - Getters

- (NSManagedObjectContext *)mainQueueContextWithDB:(NSString *)db
{
actualDB = db;
if (!_mainQueueContext) {
    _mainQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    _mainQueueContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
}

return _mainQueueContext;
}

- (NSManagedObjectContext *)privateQueueContextWithDB:(NSString *)db
{
actualDB = db;
if (!_privateQueueContext) {
    _privateQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    _privateQueueContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
}

return _privateQueueContext;
}

#pragma mark - Stack Setup

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (!_persistentStoreCoordinator) {
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
    NSError *error = nil;

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self persistentStoreURL] options:[self persistentStoreOptions] error:&error]) {
        NSLog(@"Error adding persistent store. %@, %@", error, error.userInfo);
    }
}

return _persistentStoreCoordinator;
}

- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
    return _managedObjectModel;
}
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];

return _managedObjectModel;
}

- (NSURL *)persistentStoreURL
{
return [[NSFileManager appLibraryDirectory] URLByAppendingPathComponent:actualDB];
}

- (NSDictionary *)persistentStoreOptions
{
return @{NSInferMappingModelAutomaticallyOption: @YES, NSMigratePersistentStoresAutomaticallyOption: @YES};
}

@end

【问题讨论】:

    标签: iphone sqlite core-data ios7 core-data-migration


    【解决方案1】:

    您可以尝试将 journal_mode 更改为 DELETE(猜测 WAL 在 iOS 7 及更高版本的 Core Data 中是默认设置?!?)。我使用的持久性存储选项对数十个数据模型更改没有任何问题:

    NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                    @{@"journal_mode" : @"DELETE"}, NSSQLitePragmasOption, nil];
    

    希望对你有帮助...

    关于http://www.sqlite.org/pragma.html上的日记模式:

    "DELETE 日志模式是正常行为。在 DELETE 模式下,回滚日志在每个事务结束时被删除。确实,删除操作是导致事务提交的操作。(参见标题为文档SQLite 中的原子提交以获取更多详细信息。)"

    【讨论】:

      猜你喜欢
      • 2015-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      相关资源
      最近更新 更多