传递ManagedObjectContext以使用具有根UITabBarController的故事板来查看控制器

Ada*_*ach 6 core-data uitabbarcontroller uinavigationcontroller ios5 uistoryboard

使用故事板,您无法轻松访问appDelegate中的第一个视图控制器(尽管您prepareForSegue可以轻松地将ManagedObjectContext传递到导航堆栈中.

我已经决定给每个视图控制器(或每个视图控制器的超类)要求Core Data访问一个moc成员:

@synthesize moc = _moc;
@property (nonatomic) __weak NSManagedObjectContext *moc;
Run Code Online (Sandbox Code Playgroud)

我对此感到不安,因为它似乎不是一种非常优雅的方式 - 代码太多了.但直接分配需要在viewControllers数组中指定绝对索引,并在每次ManagedObjectContexts的需求发生更改时更改appDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;

    // rootView gets a tab bar controller
    for(UINavigationController *navController in tabBarController.viewControllers) {

        for(UIViewController *viewController in navController.viewControllers) {

            if([viewController respondsToSelector:@selector(setMoc:)]) {
                [viewController performSelector:@selector(setMoc:) withObject:self.managedObjectContext];
                NSLog(@"Passed moc to %@", [viewController description]); 
            }
        }
    }

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

这种方法有哪些缺陷,有更好的方法吗?尝试更通用是否更好:

- (void)assignManagedObjectContextIfResponds:(UIViewController *)viewController {

    if([viewController respondsToSelector:@selector(setMoc:)]) {
        [viewController performSelector:@selector(setMoc:) withObject:self.managedObjectContext];
        NSLog(@"Passed moc to %@", [viewController description]); 
    }

}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSMutableArray *viewControllers = [NSMutableArray array];

    UIViewController *firstLevelViewController = self.window.rootViewController;

    if([firstLevelViewController respondsToSelector:@selector(viewControllers)]) {

        NSArray *firstLevelViewControllers = [firstLevelViewController performSelector:@selector(viewControllers)];

        for(UIViewController *secondLevelViewController in firstLevelViewControllers) {

            if([secondLevelViewController respondsToSelector:@selector(viewControllers)]) {

                NSArray *secondLevelViewControllers = [secondLevelViewController performSelector:@selector(viewControllers)];

                for(UIViewController *thirdLevelViewController in secondLevelViewControllers) {

                    [viewControllers addObject:thirdLevelViewController];
                }

            } else {
                [viewControllers addObject:secondLevelViewController];
            }
        }
    } else {
        // this is the simple case, just one view controller as root
        [viewControllers addObject:firstLevelViewController];
    }

    // iterate over all the collected top-level view controllers and assign moc to them if they respond
    for(UIViewController *viewController in viewControllers) {
        [self assignManagedObjectContextIfResponds:viewController];
    }

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

小智 2

亚当,

当我探索故事板时,我几乎以与您相同的方式进行操作,只是我使每个具有 MOC 属性的视图控制器都符合协议。

那里没有什么显着不同,所以我会继续。

我认为重点是故事板,在我看来,是半生不熟的。来自 .Net 背景的人显然缺少的是与 IoC 容器相结合的对象构建器框架。当苹果添加故事板时,将会非常棒。当故事板框架可以查看destinationViewController、确定它的依赖关系并解决容器生命周期中的依赖关系时,效果会很棒。目前,它真正能做的就是查看destinationViewController 并为您初始化一个通用的,但用途有限。

不幸的是,因为这是一个不成熟的解决方案,所以我现在坚持使用传统方法,所以我所有的视图控制器都是手动分配和初始化的,更重要的是,我已经向每个视图控制器添加了一个方法 initWithMO​​C:( MOC *)moc;

我内心的架构师告诉我这段代码更加健壮,我想这是否值得权衡只是一个意见问题。

还有其他人想出更好的方法吗?

加利福尼亚州。