我正在编写一个使用带有多个标签视图的标签控制器的测试程序。该程序下载多个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设计模式非常陌生,我试图找出最合适的方法来做这些事情!我现在得到的是什么,但我想知道是否有看不见的陷阱或未来的问题?谢谢!
答案 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
模式