1

我有一个具有不同控制器的应用程序,它们都在同一个 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 打开,但据我所知,不建议这样做......

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

4

2 回答 2

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”远离那个逻辑控制,因为他只有在上下文存在时才会被调用/创建。

于 2012-10-14T14:21:52.580 回答
2

我在同样的问题上苦苦挣扎,我通过使用NSNotificationCenter.

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

我用那个监听器来调用一个reloadData方法。在一个沉重的应用程序中,这可能是一个问题,因为viewcontroller加载空白,然后重新加载数据,但这是一个精简的应用程序,而且它很明显 -viewController加载与managedObjectContext.

于 2013-07-10T14:39:20.240 回答