Передача ManagedObjectContext в контроллеры просмотра с использованием раскадровок с корневым UITabBarController

Используя раскадровки, у вас нет легкого доступа к первому контроллеру представления в appDelegate (хотя, как только вы выполните prepareForSegue , вы сможете легко передать ManagedObjectContext вниз по стеку навигации.

Я решил предоставить каждому контроллеру представления (или суперклассу каждого контроллера представления), требующему доступа к 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 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;
}

Каковы подводные камни этого подхода h и есть ли способ лучше? Не лучше ли попытаться использовать более общий характер:

- (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;
}
6
задан Adam Eberbach 28 February 2012 в 05:08
поделиться