iOS CoreData:如何设置核心数据“连接”?斯坦福大学UIDocument与Apple模板?

时间:2013-12-31 09:36:28

标签: ios objective-c core-data uimanageddocument

我已经完成了斯坦福大学的课程,并在讲座中设置了我的第一个应用程序和核心数据。大概是这样的(我现在将代码转移到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有什么区别?有更好还是更差?

3 个答案:

答案 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