2011-12-12 74 views
3

我正在编写一个测试程序,它使用带有多个选项卡视图的选项卡控制器。该程序下载多个XML文件,通过Core Data解析并填充sqlite表。 Core Data变量和函数位于Xcode创建的代码之后的App Delegate文件中。共享托管对象上下文

我开始通过简单地将managedObjectContext变量传递到需要它的每个子视图中,如我在App代表初始化它,例如:

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

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

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

我现在已经把此getter,只是指回应用程序委托中需要参考MOC的所有类:

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

我很新的可可/ iOS的设计patters正在尝试找出做这些事情的最正确方法!我现在有的工作,但我想知道是否有未知的陷阱或未来的问题?谢谢!

+0

”是否完全删除并重新初始化所有持久性存储文件过度杀毒?“大概。你可以删除所有的对象? – jrturton

+0

@jrturton删除所有对象绝对值得一试。但是如果它们中有很多,它可能会很慢。 CoreData不是数据库。 – tonklon

+0

@tonklon - 当然。但是从这个问题我们不知道有多少物体。你的回答非常好。重新创建VC堆栈是要走的路 – jrturton

回答

2

恕我直言,经过managedObjectContext到ViewControllers是很好的做法。它使测试更容易,并创建更好的可重用ViewController。

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

删除所有对象的最快和最有效的方法实际上是删除存储文件。 NSManagedObjectContext为持久存储协调器提供了一个setter。您是否尝试使用新文件创建新storeCoordinator,将其设置为MOC的storeCoordinator,然后释放旧协调器并删除旧文件?您可能需要发送通知,因为所有ViewController都必须发布其可能保留的managedObjects。

我刚才想到的另一个想法是我完全删除了完整的viewController堆栈,然后使用新的managedObjectContext重新创建它。您可以轻松地下载,解析并将新数据保存到其自己的独立managedObjectContext(具有自己的persistentStoreController和自己的商店)中。一旦完成,从窗口中删除所有控制器,跟踪显示控制器。然后移动新存储文件覆盖旧存储文件,然后重新创建viewController堆栈。虽然这听起来像是一个昂贵的操作,但事实并非如此。在我的情况下,交换机在用户界面中甚至不明显。保留viewControllers的优点在于,旧的managedObjects仍然潜伏在某处,从而导致需要额外编辑的代码更少。如果你的viewControllers已经按照苹果公司的建议设置好了,那么这个开关就会“正常工作”。 “

+0

关于viewController堆栈的有趣想法...我不得不考虑那一点!谢谢 – Raolin

1

工作时使用Singleton模式没有最好的方式,但良好的实现。您最后一次通过应用程序代理访问上下文的解决方案很好。请记住,在这种情况下,如果实例变量已被合并,则不能使用该实例变量。

我想你的对象需要知道持久数据何时被重置,因此他们正在使用新的上下文。您可以使用一个实例变量来检查它:

@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_; 
} 
相关问题