2014-09-11 156 views
0

我有一個應用程序與兩個sqlite數據庫和兩個xcdatamodel's。所以,每件事情都很好,除非我想更改或添加一些屬性到其中一個模型。問題核心數據遷移

我正在創建一個新的模型版本並對其進行更改。設置當前模型版本之後,我開始我的應用程序並獲得以下情況例外:

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 

回答

0

您可以嘗試改變journal_mode來刪除(猜測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模式下,回滾日誌在每個事務結束時被刪除,事實上,刪除操作是導致事務提交的動作(請參閱標題爲Atomic Commit In SQLite瞭解更多細節。)「