核心数据初始化

时间:2016-09-18 16:47:20

标签: ios objective-c core-data appdelegate apple-documentation

查看Apple文档,我看到他们建议从AppDelegate中删除Core Data初始化代码。他们的方法如下。

我不明白以下内容

  1. 文档中的以下句子。如何回复app delegate?我在下面的代码片段中看不到一个。这是他们希望我们添加的内容。
  2. 通过使用完成块初始化单独的控制器对象,您已将Core Data堆栈移出应用程序委托,但仍然允许回调应用程序委托,以便用户界面可以知道何时开始请求数据。

    1. AppDelegate调用DataController的init,然后调用initializeCoreData。但是initializeCoreData在后台线程中设置持久性存储协调器。这意味着如果我们转换到应用程序的第一个视图并且其视图控制器从核心数据请求数据,那么事情尚未设置。这不是一个问题吗?这是否意味着他们希望我们展示不同的发布屏幕&注册一个回调,告诉我们在转移到实际第一个应用程序视图之前已完成CoreData初始化。
    2. 文档中的AppDelegate代码

      -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      
          [self setDataController:[[DataController alloc] init];
          // Basic User Interface initialization
          return YES;
      }
      

      文档中的DataController代码

      @interface MyDataController : NSObject
      
      @property (strong) NSManagedObjectContext *managedObjectContext;
      
      -(void)initializeCoreData;
      
      @end
      
      @implementation MyDataController
      
      -(id)init {
      
          self = [super init];
          if (!self) return nil;
      
          [self initializeCoreData];
      
          return self;
      }
      
      - (void)initializeCoreData {
      
          NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
          NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
          NSAssert(mom != nil, @"Error initializing Managed Object Model");
      
          NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
          NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
          [moc setPersistentStoreCoordinator:psc];
          [self setManagedObjectContext:moc];
          NSFileManager *fileManager = [NSFileManager defaultManager];
          NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
          NSURL *storeURL = [documentsURL URLByAppendingPathComponent:@"DataModel.sqlite"];
      
          dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
              NSError *error = nil;
              NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
              NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
              NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);
          });
      }
      

2 个答案:

答案 0 :(得分:1)

1)

In the Core Data programming guide you're looking at,作者正在从App Delegate中取出Core Data(它往往会混淆许多额外的代码,开发人员应该将这些代码拆分成单独的对象)。

其余文档解释说:

  

建议在自己的内核中创建Core Data堆栈   顶级控制器对象和应用程序委托   初始化该控制器对象并保持对它的引用。这个   行动将促进其内部核心数据代码的整合   拥有自己的控制器,并保持应用程序委托相对干净。

此外:

  

将持久性存储(NSPersistentStore)添加到   持久性商店协调员(NSPersistentStoreCoordinator)到a   背景队列。这个动作可能需要一段时间,而且   在主队列上执行它可能会阻止用户界面   导致应用程序终止。

     

将持久性存储添加到持久性存储中   协调器,然后您可以回调主队列并请求   用户界面完成并显示给用户

所以是的,在第一个视图控制器显示时,CoreData可能不一定完全正常,但是如果你有一个观察者从该后台队列中寻找NSNotification,你可以告诉你的UI何时是CoreData准备好依赖。

2)

[DataController init]DataController返回之前不会返回initializeCoreData对象,因此在didFinishLaunchingWithOptions返回之后您的UI才会显示,并且您应该已经拥有{ {1}}对象。

答案 1 :(得分:0)

方法YES的返回applicationDidFinishLaunchingWithOptions是关键。

核心数据堆栈的初始化在方法返回之前或者在任何视图控制器初始化之前发生。 一旦应用程序被通知它确实正在启动,核心数据堆栈就会被初始化。仅在整个初始化过程之后,该方法返回YES。之后故事板与其初始控制器一起加载,然后初始控制器的viewDidLoad被加载。

所以在某种程度上,在初始控制器甚至在屏幕之前很长一段时间,核心数据堆栈都已加载。

希望这可以帮助你理解。

相关问题