传递ManagedObjectContext以使用具有根UITabBarController的storyboard查看控制器 [英] Passing ManagedObjectContext to view controllers using storyboards with a root UITabBarController

查看:223
本文介绍了传递ManagedObjectContext以使用具有根UITabBarController的storyboard查看控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用storyboard,你不容易访问appDelegate中的第一个视图控制器(虽然一旦你做了 prepareForSegue ,就很容易将ManagedObjectContext传递到导航堆栈。 p>

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

  @synthesize moc = _moc; 
@property(nonatomic)__weak NSManagedObjectContext * moc;

我很担心它,因为它似乎不是一个非常优雅的方式 - 太多的代码。但直接分配需要指定绝对索引到viewControllers数组和更改appDelegate每时间要求ManagedObjectContexts更改

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

// rootView获取标签栏控制器
(在tabBarController.viewControllers中的UINavigationController * navController){

for(UIViewController * viewController in navController.viewControllers){

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

return YES;
}

这种方法有什么缺陷,有更好的方法吗?是更好的尝试和更通用:

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

if([viewController responsesToSelector:@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 responsesToSelector:@selector(viewControllers)]){

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

for(UIViewController * secondLevelViewController in firstLevelViewControllers){

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

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

(UIViewController * thirdLevelViewController in secondLevelViewControllers){

[viewControllers addObject:thirdLevelViewController];
}

} else {
[viewControllers addObject:secondLevelViewController];
}
}
} else {
//这是简单的情况,只有一个视图控制器为root
[viewControllers addObject:firstLevelViewController];
}

//遍历所有收集的顶级视图控制器,并为他们分配moc,如果他们响应
(UIViewController * viewController在viewControllers){
[self assignManagedObjectContextIfResponds:viewController];
}

return YES;
}


解决方案

Adam,



虽然我正在探索storyboards,但我几乎是以同样的方式,除非我让每个视图控制器有一个MOC属性符合协议。



这里没有什么明显的不同,所以我会继续。



我想要的是Storyboards,IMO 。来自.Net背景,显然缺少的是与IoC容器耦合的对象构建器框架。
当苹果添加,故事板将是真棒。当storyboard框架可以查看destinationViewController,确定它的依赖和解决那些从容器生活将是巨大的。现在,它可以真正做的是看看destinationViewController和init你是一个通用的,这是有限的使用。



不幸的是,因为它是一个半烤的解决方案我现在坚持传统的方法,所以所有我的视图控制器是alloc'd和init'd手动,更重要的是,我已经添加一个方法到每个视图控制器initWithMO​​C:(MOC *)moc;



我的建筑师告诉我这个代码更加健壮,我想这是一个关于是否值得权衡的问题。



任何人都有更好的方法吗?



CA。


Using storyboards you have no easy access to the first view controller in appDelegate (though once you do prepareForSegue makes it easy to pass the ManagedObjectContext down the navigation stack.

I've settled on giving each view controller (or superclass of each view controller) requiring Core Data access a moc member:

@synthesize moc = _moc;
@property (nonatomic) __weak NSManagedObjectContext *moc;

I'm uneasy about it because it doesn't seem a very elegant way to do it - too much code. But assigning directly requires specifying absolute indexes into the viewControllers arrays and changing appDelegate every time the requirement for ManagedObjectContexts change

- (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;
}

What are the pitfalls of this approach and is there a better way? Is it better to try and be more generic:

- (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;
}

解决方案

Adam,

Whilst I was exploring storyboards I pretty much did it the same way you did except I made each of my view controllers that had a MOC property conform to a protocol.

There's nothing significantly different there, so I'll move on.

I think the point is Storyboards, IMO, are half-baked. Coming from a .Net background what is obviously missing is an object builder framework coupled with an IoC container. When Apple add that Storyboards will be awesome. When the storyboard framework can look at the destinationViewController, determine it's dependencies and resolve those from a container life will be great. For now, all it can really do is look at the destinationViewController and init you a generic one, which is of limited use.

Unfortunately, because it's a half-baked solution I'm sticking with the traditional approach for now so all my view controllers are alloc'd and init'd manually and more importantly I've added a method to each view controller to initWithMOC:(MOC *)moc;

The architect in me is telling me this code is more robust, I guess it's a matter of opinion as to whether it's worth the trade-off.

Anyone else come up with a better way?

CA.

这篇关于传递ManagedObjectContext以使用具有根UITabBarController的storyboard查看控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆