共享托管对象上下文

时间:2011-12-12 06:48:57

标签: objective-c ios cocoa-touch core-data

我正在编写一个使用带有多个标签视图的标签控制器的测试程序。该程序下载多个XML文件,通过Core Data解析和填充sqlite表。核心数据变量和函数位于Xcode创建代码之后的App Delegate文件中。

我开始只是将managedObjectContext变量传递给需要它的每个子视图,因为我在App Delegate中初始化它,例如:

FirstViewController *vc1;
vc1 = [[[FirstViewController alloc] initWithNibName:@"FirstView" bundle:nil] autorelease];
[vc1 setManagedObjectContext:self.managedObjectContext];

但是,我有一个删除整个数据存储的函数(resetData) - 删除持久存储文件并将所有Core Data变量(managedObjectContext,managedObjectModel,persistentStore等)设置为nil,重新初始化所有内容。这样程序就可以从头开始并重新下载网络中的所有数据。发生这种情况时,子视图现在指向旧的managedObjectContext。

更新所有子视图中的managedObjectContext变量的最佳方法是什么?从resetData函数手动更新子视图的managedObjectContext变量?使用NSNotificationCenter向所有视图发送通知?完全删除并重新初始化所有持久存储文件是否过度?

我目前已经把这个getter引用回所有需要引用MOC的类中的App Delegate:

- (NSManagedObjectContext *)managedObjectContext {
    MyAppDelegate* ad = (MyAppAppDelegate*)[[UIApplication sharedApplication] delegate];
    return [ad managedObjectContext];
}

我对Cocoa / iOS设计模式非常陌生,我试图找出最合适的方法来做这些事情!我现在得到的是什么,但我想知道是否有看不见的陷阱或未来的问题?谢谢!

3 个答案:

答案 0 :(得分:2)

恕我直言将managedObjectContext传递给ViewControllers是一种很好的做法。它使测试更容易,并创建更好的可重用ViewControllers。

实现所需结果的一种方法是简单地从商店中删除所有对象,同时保持CoreData堆栈不变。所有视图控制器都只使用与以前相同的上下文,但它不再包含对象。但这可能会变慢,具体取决于对象的数量。

删除所有对象的最快,最有效的方法是删除存储文件。 NSManagedObjectContext为持久性存储协调器提供了一个setter。您是否尝试使用新文件创建新的storeCoordinator,将其设置为MOC的storeCoordinator,然后释放旧协调器并删除旧文件?在这种情况下,您可能需要发送通知,因为所有ViewControllers都必须释放它们可能保留的托管对象。

我想到的另一个想法是,我之前使用的是完全删除完整的viewController堆栈,然后使用新的managedObjectContext重新创建它。您可以在后台轻松下载,解析并将新数据保存到其自己的独立managedObjectContext(具有自己的persistentStoreController和自己的商店)中。完成后,从窗口中删除所有控制器,显示跟踪控制器。然后移动新的存储文件覆盖旧存储文件并重新创建之前的viewController堆栈。虽然这听起来像是一项昂贵的操作,但事实并非如此。在我的情况下,UI中的开关甚至不明显。保持viewControllers的优势在于,旧的托管对象仍然潜伏在某处,因此导致需要额外编辑的代码更少。如果你的viewControllers已经按照苹果推荐的方式进行设置,那么这个开关将“正常工作”。

答案 1 :(得分:1)

没有最好的方法,但良好的实施。您通过应用程序委托访问上下文的最后一个解决方案很好。请记住,在这种情况下,如果它是合成的,则不能使用实例变量。

我认为你的对象需要知道何时重置持久性数据,因此他们正在使用新的上下文。您可以使用实例变量进行检查:

@synthesize managedObjectContext = moc_ ;

然后你可以测试:

- (NSManagedObjectContext *)managedObjectContext {
    MyAppDelegate* ad = (MyAppAppDelegate*)[[UIApplication sharedApplication] delegate];

    if(moc_ != [ad managedObjectContext]) {
          // NEW CONTEXT. DO ANYTHING NEEDED TO RESET OBJECT
    }

    // Use property to change value to ensure set rules (retain for example).
    [self setManagedObjectContext:[ad managedObjectContext]];

    return moc_;
}

答案 2 :(得分:0)

在使用Singleton

时,我通常会使用CoreData模式