我已经完成了斯坦福大学的课程,并在讲座中设置了我的第一个应用程序和核心数据。大概是这样的(我现在将代码转移到app delegate中):
- (void)setupFetchedResultsController
{
NSError *error = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MainCategory"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"position" ascending:YES]];
[self.budgetDatabase.managedObjectContext executeFetchRequest:request error:&error];
self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request
managedObjectContext:self.budgetDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
-(void)useDocument
{
if(![[NSFileManager defaultManager]fileExistsAtPath:[self.budgetDatabase.fileURL path]]){
[self.budgetDatabase saveToURL:self.budgetDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.budgetDatabase.documentState == UIDocumentStateClosed){
[self.budgetDatabase openWithCompletionHandler:^(BOOL success){
[self setupFetchedResultsController];
}];
} else if (self.budgetDatabase.documentState == UIDocumentStateNormal){
[self setupFetchedResultsController];
}
}
- (void)viewWillAppear:(BOOL)animated
{
//Initialize database
[super viewWillAppear:animated];
if(!self.budgetDatabase){
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentationDirectory inDomains:NSUserDomainMask] lastObject];
[url URLByAppendingPathComponent:@"BudgetDatabase"];
self.budgetDatabase = [[UIManagedDocument alloc]initWithFileURL:url];
}
}
Apple模板中的代码(如果在创建Xcode项目时检查“CoreData”)看起来非常不同且更复杂。这UIManagedDocument
有什么区别?有更好还是更差?
答案 0 :(得分:3)
UIManagedDocument
专为具有文档的应用程序而设计,因此名称。斯坦福大学的课程正在使用它来跳过核心数据的构建,以使学生“更容易”。不幸的是,从长远来看,它们让你的生活变得更加艰难。
请勿使用UIManagedDocument
。从Apple模板开始,学习如何站起来使用Core Data堆栈。您将以这种方式获得更多知识,更好地理解代码正在做什么(不那么神奇)并且将作为开发人员进步。
UIManagedDocument
有很多尖锐的边缘,当事情开始变得复杂时很难处理。跳过它。
UIManagedDocument
并非旨在成为应用程序的单个Core Data堆栈,而是用于基于文档的应用程序。
你不能保证豁免(不破坏它)的事实是一个很大的风险。它也是一个不透明的结构,你不应该深入到它的私人环境中。
事实上,它会自行保存,无法阻止它,这在我的书中很危险。您很容易想要保存上下文(沉重的UI,播放视频等)并且它决定保存。糟糕的用户体验。
除此之外,它还可以与外部文件结构一起使用,这些结构使用起来很复杂,而且风险更大。
它能拯救你什么?没有。这不是代码节省,因为站起来正常的核心数据堆栈的6行代码被很多异步代码所取代,以便站起来并部署UIManagedDocument
。
您如何处理迁移?当迁移需要额外的工作量而不是轻量级迁移时会发生什么?
需要考虑很多事情。
我书中的第一项是随机和异步保存。我只是不喜欢放弃这种控制的想法。
答案 1 :(得分:1)
简单回答如下。 UIManagedDocument
抽象了与Core Data Stack的交互。
UIManagedDocument
保存会自动处理,通常在后台线程中以异步方式执行。此外,它还包含一些处理iCloud内容的功能。通常,它可以被视为核心数据堆栈的包装。
没有更好或更糟的方法。 UIManagedDocument
旨在用于基于文档的应用程序。有关详细信息,请参阅UIDocument class reference。
关于核心数据堆栈没有任何复杂或困难。只有更多的代码。但在幕后,UIManagedDocument
为您包装了该代码。
可以轻松减少核心数据堆栈的代码。关于如何简化Apple提供的模板的好文章可以在Core Data Stack @jrturton 中找到。特别是,代码简化了6个步骤,可以遵循逻辑流程。
正如之前的回答中所述。
与
NSFetchedResultsController
相关的内容应该留在 控制器类。例如,它可以保留在特定的UIViewController
课程,UITableViewController
课程或课程 其他类可以从中扩展的类(即基数)UIViewController
类)。
希望它有所帮助。
答案 2 :(得分:0)
我个人也开始使用斯坦福课程建议的UIDocument
上下文,这对于一个简单的应用程序是好的,这是最简单的方法。当我的应用程序增长并且我需要在整个应用程序中访问coredata时,我必须处理在应用程序的不同生命阶段访问/打开/创建文档的额外代码。
然后我转到了Apple模板,我很高兴。无论如何,全部都在appDelegate
。我建议您阅读本文以处理具有父子关系的后台线程的核心数据Multi-Context CoreData。