如何通过UIManagedDocument异步打开NSManagedObjectContext

时间:2012-10-14 12:31:08

标签: iphone ios core-data nsmanagedobjectcontext

我有一个带有不同控制器的应用程序,它们都在同一个NSManagedObjectContext上运行。

我的方法是在我的AppDelegate中初始化NSManagedObjectContext并将其注入所有控制器。

我正在通过打开这样的UIManagedDocument初始化我的NSManagedObjectContext:

UIManagedDocument* databaseDoc = [[UIManagedDocument alloc] initWithFileURL:url];

if (![[NSFileManager defaultManager] fileExistsAtPath:[databaseDoc.fileURL path]]) {
    [databaseDoc saveToURL:databaseDoc.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
        myController.managedObjectContext = databaseDoc.managedObjectContext;
    }];
} else if (databaseDoc.documentState == UIDocumentStateClosed) {
    [databaseDoc openWithCompletionHandler:^(BOOL success) {
        myController.managedObjectContext = databaseDoc.managedObjectContext;
    }];
} else if (databaseDoc.documentState == UIDocumentStateNormal){
    myController.managedObjectContext = databaseDoc.managedObjectContext;
}

现在我的问题是,打开UIManagedDocument是异步发生的,NSManagedObjectContext只在完成块中可用。

如何确保控制器始终具有有效的NSManagedObjectContext?当然,问题发生在启动时,即控制器想要在他的" viewDidLoad"中使用NSManagedObjectContext。方法,AppDelegate中的完成块尚未运行...

一种方法可能是"等待"在AppDelegate中,直到UIDocument打开,但据我收集this is not recommended ...

我想避免污染"污染"我的控制器的代码处理打开NSManagedObjectContext的异步性质...但也许这是一个天真的愿望?

2 个答案:

答案 0 :(得分:3)

在你的appDelegate中:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    MyWaitViewController* waitController = [[MyWaitViewController new] autorelease];
    self.window.rootViewController =  waitController;

// then somewheres else, when you get your context
  [databaseDoc saveToURL:databaseDoc.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
        myContextController.managedObjectContext = databaseDoc.managedObjectContext;
        self.window.rootViewController    = myContextController;
        // note that at this point when the viewDidLoad method will get called
        // it will have his managedObjectContext and his view already available.
        // you can change your rootController, or push another viewController into the
 // stack. Depending on what u want from the GUI side

    }];
    return YES;
}

请注意,您将GUI逻辑部署到MyWaitViewController + AppDelegate端。但是你让你的“myContextController”远离那个逻辑控件,因为只有在存在上下文时才会调用/创建它。

答案 1 :(得分:2)

我正在努力解决同样的问题,我使用NSNotificationCenter想出了它。

  • 在成功处理程序中初始化NSManagedObjectContext时,添加发送通知。
  • 然后,将听众添加到viewDidLoad的第一个ViewController

我使用该侦听器调用reloadData方法。在一个繁重的应用程序中,这可能是一个问题,因为viewcontroller加载空白,然后重新加载数据,但这是一个简单的,并且它是显而易见的 - viewController瞬间加载managedObjectContext