Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 共享托管对象上下文_Objective C_Ios_Cocoa Touch_Core Data - Fatal编程技术网

Objective c 共享托管对象上下文

Objective c 共享托管对象上下文,objective-c,ios,cocoa-touch,core-data,Objective C,Ios,Cocoa Touch,Core Data,我正在编写一个测试程序,它使用带有多个选项卡视图的选项卡控制器。该程序下载多个XML文件,通过核心数据解析和填充sqlite表。核心数据变量和函数位于Xcode创建代码之后的应用程序委托文件中 我一开始只是将managedObjectContext变量传递给每个需要它的子视图,就像我在应用程序委托中初始化它一样,例如: FirstViewController *vc1; vc1 = [[[FirstViewController alloc] initWithNibName:@"FirstView

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

我一开始只是将managedObjectContext变量传递给每个需要它的子视图,就像我在应用程序委托中初始化它一样,例如:

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的类中的App Delegate:

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

我对Cocoa/iOS设计模式非常陌生,我正在尝试找出最合适的方法来完成这些事情!我现在所拥有的一切都起作用了,但我想知道是否有看不见的陷阱或未来的问题?谢谢

在使用
CoreData
时,我通常使用
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_;
}

IMHO将managedObjectContext传递到ViewControllers是一种良好的做法。它使测试更容易,并创建更好的可重用ViewController

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

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


我刚刚想到的另一个想法,也是我以前使用过的,就是完全删除完整的viewController堆栈,然后使用新的managedObjectContext重新创建它。您可以在后台轻松下载、解析新数据并将其保存到它自己单独的managedObjectContext中(具有它自己的persistentStoreController和自己的store)。完成后,从窗口中删除所有控制器,跟踪显示的控制器。然后移动新的存储文件,覆盖旧的存储文件,并像以前一样重新创建viewController堆栈。虽然这听起来像是一项昂贵的手术,但事实并非如此。在我的例子中,切换在UI中甚至不明显。与保留viewControllers相比,保留viewControllers的优势在于,旧的ManagedObject仍然潜伏在某个地方的可能性要小得多,从而减少了需要额外编辑的代码。如果您的ViewController已经按照苹果公司建议的方式进行了设置,则此开关“正常工作”的可能性很高。

“完全删除并重新初始化所有持久存储文件是否过度?”。您可以删除所有对象吗?@jrturton删除所有对象绝对值得一试。但是如果有很多的话,速度可能会很慢。CoreData不是数据库。@tonklon-当然可以。但从这个问题我们不知道有多少物体。你的回答很好。重新创建VC堆栈才是解决问题的方法我选择当前路线的原因是删除对象似乎相当慢。关于viewController堆栈的有趣想法…我必须仔细考虑一下!谢谢