我如何使用storyboard传递managedObjectContext来初始化下一个控制器



我有这段代码来跳转到第二个storyboard

UIStoryboard *secondStoryBoard = [UIStoryboard storyboardWithName:@"SpaceView" bundle:nil];
// Load the initial view controller from the storyboard.
NRGSpacesNavController *nav = [secondStoryBoard instantiateInitialViewController];
nav.managedObjectContext = self.managedObjectContext;
NRGSpacesViewController *spacesController = [nav.viewControllers firstObject];
spacesController.space = space;
[self presentViewController:nav animated:YES completion:nil];

问题是在第二个故事板上实例化的控制器需要为它的容器视图使用managedObejectContext。在prepareForSegue之前加载的唯一东西是实际的init方法。但我似乎可以在init方法上添加上下文。ViewDidLoad和其他东西都太迟了。如果可以的话,我希望保留故事板,但可以通过编程来完成所有操作

我尝试将上下文添加到nag控制器,因为你可以做到它不工作。上下文为nil。

感谢您的帮助,欢迎您提建议

在您要移动到的UIViewController上创建一个属性,并在prepareForSegue:中设置该属性

在驱动转换的UIViewController中:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"YourVCSegue"]) {
         NextViewController *nextVC = segue.destinationViewController;
         nextVC.myManagedObjectContext = self.managedObjectContext;
    }
}

UIViewController接口中转换为:

@interface NextViewController : UIViewController
@property (nonatomic,strong) NSManagedObjectContext *myManagedObjectContext;
@end 

这将在init方法被调用之后(必须被调用,否则你将在nil对象上设置)和viewDidLoad被调用之前设置属性。

另一个选项(不可取)是创建一个Singleton helper类,它持有NSManagedObjectContext,并且你可以在整个应用程序中访问它。例句:

[[MyCoreDataHelperClass sharedInstance] managedObjectContext];

关于在你的应用程序中访问NSManagedObjectContext的信息,请参阅文档

你可以在prepareForSegue方法中将东西分配给即将到来的视图控制器。但视图控制器不是存储context的好地方。(导航控制器是一个视图控制器)。

更好的方法是要么将托管对象上下文创建为单例,要么有一个单独的类来处理所有核心数据交互,并在该类中创建上下文。写一个getter来获取上下文

好的,我在这里得到了一个修复。

  // Load the initial view controller from the storyboard.
NRGSpacesNavController *nav = [secondStoryBoard instantiateInitialViewController];
NRGSpacesViewController *spacesController = [nav.viewControllers firstObject];
spacesController.space = space;
spacesController.managedObjectContext = self.managedObjectContext;
[self presentViewController:nav animated:YES completion:nil];

看来我把货物装载的顺序搞错了。我还移动了一些东西来设置context属性。这段代码首先运行,然后是容器的viewDidLoad(在spacecontroller中),然后是spacecontroller的viewDidLoad。我在那些viewDidLoads中加载我的东西我使用委托让容器知道被包含的什么时候会加载它们的视图。

尽管有些人可能会发现这种反模式,但我倾向于使用唯一的CoreDataController,它管理上下文的创建和共享。我从来不喜欢传递上下文的想法,尤其是在多线程环境中。

话虽如此,我还是要使用下面的一个解决方案:

i)创建一个带有NSManagedObjectContext属性的协议,并让所有相关的控制器实现它。

@protocol MyProtocol
@property(nonatomic,strong) NSManagedObjectContext mySharedContext;
@end

ii)而不是传递上下文,如果应用程序是一个向下钻取接口,没有繁重的多线程,即列表和细节,我将使用相同的协议方法,但声明一个通用的NSManagedObject,我可以从中检索上下文。

@protocol MyProtocol
@property(nonatomic,strong) NSManagedObject myObject;
@end

然后在目标控制器

-(void)myMethod {
   // optional casting
   MyParticularManagedObject *obj = (MyParticularManagedObject*)self.myObject;
   NSManagedObjectContext *ctx = obj.managedObjectContext;
   // rest of the code....      
}
最后要注意的是,看看这是否可能是你的情况:

prepareForSegue不会在performSegue:withIdentifier: with popover style

之后被调用

相关内容

最新更新