好的,假设我正在制作一款观鸟应用。

有一个“官方”鸟类数据库。存储在一个UIManagedDocument中。它用于填充所有鸟类的UITableView以及带有图片和数据的每个鸟类的详细视图。将来,该数据库将随着更多鸟类而升级。

然后,用户可以去乡下拍鸟的照片。他将它们添加到应用程序的另一部分,称为“日记”,当他识别出该鸟时,便将其与一只“官方”鸟联系起来。此信息(所有用户收集的数据)应使用iCloud备份。它也用于填充日记的UITableView和详细视图。

从日记的详细视图中,您可以转到“官方”鸟的详细视图。从该视图中,您可以转到用户日记中包含该鸟所有寄存器的列表。

问题是:我应该为每个用户条目使用一个UIManagedDocument吗?带有缩略图的UITableView如何工作?

最佳答案

UIDocument是物理文件包装程序的管理类。 UIManagedDocument是提供CoreData堆栈的子类。

File Wrapper仅仅是文件夹或文件的抽象。对于UIManagedDocument,该文件夹包含CoreData堆栈连接到的SQLite数据库。

与在每个写作段落中使用单独的Word文档相比,您不会在日记条目中使用单独的Document。

由于您的应用程序听起来更像Apple所说的“Shoebox应用程序”,在该应用程序中,一个用户拥有一堆数据,他们可以在其中添加和从中删除数据,因此并不需要使用文档体系结构。但是,说这个UIManagedDocument为您提供了一个免费的堆栈,因此可能有用。

如果是我构建此应用程序,则可以采用这种方法。

  • 官方鸟类的只读数据库。该数据库是在首次启动时以及需要更新时下载的。您不应该尝试将其放入捆绑包中,因为它将变得很大。它不会在任何时候备份。
  • 一个保存您的日记条目的读写数据库。该数据库将备份到iCloud,并且在Bird数据库的升级中不会受到影响。
  • 通过使用GUID而不是CoreData关系来松散地耦合两个数据库。


  • 例如,绿头鸭的GUID可能是DUCK1234。在您的日记条目中将该GUID写为属性(例如birdGUID)。要查找所有有关绿头鸭的日记条目,请在日记数据库上的“birdGUID =='DUCK1234'”上运行查询,您会发现所有发现的时间。

    这样做的原因是,您可以升级官方的Bird Database,而不必担心损害用户数据。假设您购买了更好/更便宜的数据库,或者购买了另一个带有鸟叫声的数据库,则可以调整Schema来应对。

    编辑

    一种方法(一种简单的方法)是使用两个NSPersistentStores构建堆栈
    NSPersistentStoreCoordinator *myPersistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
    
    NSDictionary *readonly_options = @{NSReadOnlyPersistentStoreOption:@YES};
    
    [myPersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:officialBirdStoreURL options:readonly_options error:&error];
    
    NSDictionary *readwrite_opts = @{NSMigratePersistentStoresAutomaticallyOption:@YES,
      NSInferMappingModelAutomaticallyOption:@YES};
    
    [myPersistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:diaryStoreURL options:readwrite_opts error:&error];
    
    NSManagedObjectContext *workingContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];
    
    workingContext.persistentStoreCoordinator = myPersistentStoreCoordinator;
    

    由于有许多excellent Core Data tutorials,因此我不会完全解释这一点,但请注意在Bird数据库中设置NSReadOnlyPersistentStoreOption

    这不涉及使用UIManagedDocument,因为您没有对堆栈进行足够的控制。

    总结一下,从下到上的堆栈。
  • UIManagedDocument-模型控制器。处理文件包装器
    机械师并提供免费堆栈。不需要。可能会使(或不能)使多文档应用程序更容易。
  • NSManagedObjectModel-模型,核心数据的架构
    模型。
  • NSPersistentStore-模型,表示一个SQLite数据库
    磁盘。
  • NSPersistentStoreCoordinator-任意数量NSPersistentStore的控制器
  • NSManagedObjectContext-模型工作区,
    像一张便条纸。使用并保存或使用并丢弃。

  • 在此阶段,不要与UIManagedDocument捆绑在一起。它是文件系统的控制器,顶部是CoreData堆栈。它并没有开箱即用地做您想做的事情。

    担心真正的问题是如何加载两个数据库并使用它们的数据来驱动UI。

    如果以后确实很重要,则可以移动基于UIManagedDocument的体系结构。如果这是我的应用程序,我不会打扰。

    10-02 13:25