更改核心数据堆栈后使用核心数据创建 SQLite 文件后未更新
Posted
技术标签:
【中文标题】更改核心数据堆栈后使用核心数据创建 SQLite 文件后未更新【英文标题】:SQLite file not updated once created with Core Data after changing Core Data Stack 【发布时间】:2016-02-04 19:26:25 【问题描述】:我更改了现有的核心堆栈,并且我的 sqlite 文件在创建后不再更新。我可以使用核心数据保存和获取数据,但 sqlite 文件始终为空(sqlite-shm 文件被更新)。我的实施错了吗?我需要做什么才能更新我的 sqlite 文件?
//头文件
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (readonly, strong, nonatomic) NSManagedObjectContext *masterManagedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectContext *mainManagedObjectContext;
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator;
-(NSManagedObjectModel *)managedObjectModel;
-(NSManagedObjectContext *)masterManagedObjectContext;
-(NSManagedObjectContext *)mainManagedObjectContext;
-(NSManagedObjectContext *)workerManagedObjectContext;
//实现文件
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
@synthesize masterManagedObjectContext = __masterManagedObjectContext;
@synthesize mainManagedObjectContext = __mainManagedObjectContext;
//Managed object context
-(NSManagedObjectContext *)masterManagedObjectContext
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
__masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[__masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
return __masterManagedObjectContext;
- (NSManagedObjectContext *)mainManagedObjectContext
if (__mainManagedObjectContext != nil)
return __mainManagedObjectContext;
__mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__mainManagedObjectContext setParentContext:self.masterManagedObjectContext];
return __mainManagedObjectContext;
- (NSManagedObjectContext *)workerManagedObjectContext
NSManagedObjectContext *tempMOContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
tempMOContext.parentContext = [self mainManagedObjectContext];
return tempMOContext;
//Save methods
- (void)saveWorkerContext:(NSManagedObjectContext *)context
NSError *error;
[context save:&error];
if (!error)
[self saveMainContext];
- (void)saveMainContext
[self.mainManagedObjectContext performBlock:^
NSError *error = nil;
[self.mainManagedObjectContext save:&error];
if(!error)
//Write to disk after saving on the main UI context
[self saveMasterContext];
];
- (void)saveMasterContext
[self.masterManagedObjectContext performBlock:^
NSError *error = nil;
[self.masterManagedObjectContext save:&error];
if(error)
NSLog(@"CORE DATA MASTER CONTEXT ERROR : %@", error);
];
-(NSManagedObjectModel *)managedObjectModel
if (__managedObjectModel != nil)
return __managedObjectModel;
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"MyResource"
ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
NSString *modelPath = [bundle pathForResource:@"MyData"
ofType:@"momd"];
//NSLog(@"Bundle modelURL:%@",modelPath);
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
if (__persistentStoreCoordinator != nil)
return __persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyData.sqlite"];
//NSLog(@"storeURL:%@",storeURL);
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
return __persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
//尝试保存数据的示例
-(void)saveDictionary:(NSMutableDictionary *)myDictionary
NSManagedObjectContext *context = [self workerManagedObjectContext];
[context performBlockAndWait:^
NSMutableDictionary *tmpDic = myDictionary;
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
Entity *myEntity;
if ([fetchedObjects count]>0)
myEntity = [fetchedObjects lastObject];
else
myEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:context];
myEntity.value = tmpDic[@"value1"]!=nil?tmpDic[@"value1"]:@"nothing";
[self saveWorkerContext:context];
];
【问题讨论】:
【参考方案1】:我需要做什么才能让它工作?
但你也说过
我能够使用核心数据保存和获取数据...
这就是使用 Core Data “工作”的定义。如果这行得通,你就完成了。
SQLite shm 文件是 SQLite 日志。这是 SQLite 如何工作的实现细节。如果您有兴趣,可以阅读how SQLite manages its files,但这与您正在做的事情并不真正相关。
【讨论】:
也许我应该将我的问题从“我需要做什么才能让它发挥作用?”到“我需要做什么才能更新我的 sqlite 文件?”更清楚? 为什么要更新它?让 SQLite 像它想要的那样使用它的日志文件有什么问题?你想解决什么问题? @TomHarrington 仅用于测试例如迁移过程。我有相同的问题。我需要预先填充我的商店。【参考方案2】:仅当您想要生成 sqlite 文件时,在添加持久存储时使用以下选项:
@NSSQLitePragmasOption: @@"journal_mode": @"DELETE"
[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
URL:self.localStoreURL
options:@NSSQLitePragmasOption: @@"journal_mode": @"DELETE"
error:nil];
然后运行应用程序,退出,进入应用程序文件夹并在Documents
中更新您的文件。我希望这会对你有所帮助。
【讨论】:
以上是关于更改核心数据堆栈后使用核心数据创建 SQLite 文件后未更新的主要内容,如果未能解决你的问题,请参考以下文章
XCode4 - 在哪里寻找由核心数据创建的 sqlite 文件