我正在Swift中实现一个程序,我正在使用Core Data
框架。我的应用已经完成,但我决定重构核心数据栈。现在,Core Data Stack
的结构如下所示:
我看了Core Data Stack
表格Big Ranch Nerd和Github上的其他人,大多数时候,他们的Core Data Stack
看起来像这样:
我想知道是否有更好的方法以类似的方式重构我的Core Data Stack
。简而言之,这就是我使用我的Managed Object Context
:
mainContext
=所有与UI相关的任务firstPrivateContext
=用于从Firebase导入所有数据并将数据推送到登录的持久性商店secondPrivateContext
=用于在登录和注册时将设备中的联系人导入Core Data thirdPrivateContext
=用于在使用应用期间收听来自firebase的传入数据这就是我的应用程序大致正在做的事情。如果有人知道更好的做法,我愿意接受任何建议。
这是我在用户再次登录时使用的代码:
func importDataFromFirebase(){
guard let importContext = importContext else {return}
FirebaseStore.rootRef.childByAppendingPath("users/"+FirebaseStore.rootRef.authData.uid+"/forums").observeSingleEventOfType(.Value, withBlock:{
snapshot in
guard let firebaseData = snapshot.value as? NSDictionary else {return}
guard let uids = firebaseData.allKeys as? [String] else {return}
importContext.performBlock{
for uid in uids{
guard let forum = NSEntityDescription.insertNewObjectForEntityForName("Forum", inManagedObjectContext: importContext) as? Forum else {return}
FirebaseStore.rootRef.childByAppendingPath("forums/"+uid+"/posts").queryOrderedByKey().observeSingleEventOfType(.Value, withBlock: {
snapshot in
// Saving the chat's messages
guard let data = snapshot.value as? NSDictionary else {return}
importContext.performBlock{
guard let posts = NSEntityDescription.insertNewObjectForEntityForName("Post", inManagedObjectContext: importContext) as? Post else {return}
do{
try importContext.save()
}catch let error{
// Error
}
}
})
}
}
})
}
此图表显示了我想要实现的目标:
答案 0 :(得分:1)
您可以以任何方式构建CoreData堆栈,但首先回答问题 - 您想要实现的行为。 如果您想在导入内容时自动更新UI,那么您的解决方案将无效。
在private managed object context
之后persistent store coordinator
之后的重点是在后台队列中保持繁重的操作(保存到文件)。
如果您希望在导入后立即在屏幕上看到更新,则应在child private managed object context
中将parentContext
设置为main managed object context
进行导入。要更新用户界面,您可以使用NSFetchedResultsController
。这样,无论何时保存在child managed object context
中,它都会触发通知,该通知将由NSFetchedResultsController
处理并更新用户界面。
不要忘记保存完整的堆栈。仅将child managed object context
的保存称为保存到文件中是不够的。
建议写一些保存完整堆栈的方法,如下所示:
- (void)saveWithCompletionBlock:(void (^)(NSError *error))completionBlock {
static dispatch_queue_t queue = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create("CoreDataSaveQueue", 0);
});
//Retain current NSManagedObjectContext to avoid unloading
__block NSManagedObjectContext *strongSelf = self;
dispatch_async(queue, ^{
__block NSManagedObjectContext *context = strongSelf;
__block NSError *error = nil;
do {
[context performBlockAndWait:^{
if (context != nil && [context hasChanges])
[context save:&error];
context = (nil != error ? nil : context.parentContext);
}];
} while (nil != context);
dispatch_async(dispatch_get_main_queue(), ^{
if (completionBlock)
completionBlock(error);
});
//Release current NSManagedObjectContext after save completed
strongSelf = nil;
});
}
我希望我的解释会帮助您了解如何构建堆栈。