Uso de guiones gráficos que no tienen fácil acceso al primer controlador de vista en AppDelegate (aunque una vez que lo prepareForSegue
hace que sea fácil para pasar el ManagedObjectContext abajo de la pila de navegación.Pasando ManagedObjectContext para ver los controladores utilizando guiones gráficos con una UITabBarController raíz
me he decidido por dar a cada controlador de vista (o superclase de cada controlador de vista) que requiere de datos Básicos de acceder a un miembro moc:
@synthesize moc = _moc;
@property (nonatomic) __weak NSManagedObjectContext *moc;
estoy inquieto porque no parece una forma muy elegante de hacer es demasiado código. Pero asignarlo directamente requiere especificar inde absoluto equis en las matrices viewControllers y cambiar AppDelegate cada vez que el requisito para ManagedObjectContexts cambian
- (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;
}
¿Cuáles son los peligros de este enfoque y es que hay una manera mejor? ¿Es mejor tratar de ser más genérico:
- (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;
}
Sé que puedes hacer eso pero estoy tratando de evitarlo. No se puede expresar claramente por qué está mal, pero se siente de esa manera, # importando AppDelegate en todas partes. –
No está mal, es la forma de hacerlo, no tiene sentido pasar el contexto cuando puede acceder fácilmente. La importación solo es necesaria para evitar la advertencia del compilador (no error), porque siempre que puedas llamar a [UIApplication sharedApplication] desde cualquier lugar de tu código y funcione con la importación, esto es también lo que genera el Xcode para una aplicación CoreData, sorprende por qué declaras que está mal, y prefieres pasar el contexto de esa manera. Al centralizar los accesadores CoreData también obtiene más control para guardar el error, la carga diferida, lo que quiera. – Leonardo
http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html "incorrecto" quizás no era la palabra correcta. Estoy buscando lo óptimo. –