Domanda

Tramite storyboard non hai facile accesso per la prima view controller in appDelegate (anche se una volta che hai fatto prepareForSegue lo rende facile per passare il ManagedObjectContext giù lo stack di navigazione.

Mi sono depositato sul dare ogni view controller (o superclasse di ogni view controller) che richiedono i Dati principali di accedere a una moc membro:

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

Io sono a disagio su di esso, perché non mi sembra un modo molto elegante per farlo - troppo codice.Ma l'assegnazione diretta richiede di specificare assoluto indici in viewControllers matrici e cambiare appDelegate ogni volta che il requisito per ManagedObjectContexts cambiare

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

Quali sono le insidie di questo approccio e c'è un modo migliore?È meglio cercare di essere più generico:

- (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;
}
È stato utile?

Soluzione

Adamo,

Mentre stavo esplorando storyboard ho praticamente fatto lo stesso modo che hai fatto salvo che ho fatto la mia view controller che aveva una MOC proprietà conformi a un protocollo.

Non c'è niente di significativamente diverso, quindi non posso andare avanti.

Penso che il punto è Storyboard, IMO, sono cotto a metà.Proveniente da una .Netto di sfondo che è ovviamente manca è un oggetto generatore quadro accoppiato con un IoC container.Quando Apple aggiungere che gli Storyboard sarà fantastico.Quando storyboard quadro può guardare la destinationViewController, determinano le dipendenze e risolvere tali da un contenitore di vita sarà grande.Per ora, tutto si può davvero fare è guardare il destinationViewController e init è un generico, che è di uso limitato.

Purtroppo, perché è un half-baked soluzione mi sto attaccando con il tradizionale approccio così per ora tutti i miei view controller sono alloc d e init piacerebbe manualmente e, cosa più importante, ho aggiunto un metodo per ogni view controller per initWithMOC:(MOC *)moc;

L'architetto che è in me mi dice che questo codice è più robusto, credo sia una questione di opinione se vale la pena di trade-off.

Chiunque altro venire con un modo migliore?

CA.

Altri suggerimenti

Non so se ho capito correttamente, ma perché non hai lasciato l'oggetto gestito contesto direttamente in classe AppDelegate e lasciano tutta la logica per creare un'istanza.E da allora si può chiedere per essa.

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;

quindi è possibile richiamare in qualsiasi momento da qualsiasi luogo.

NSManagedObjectContext *moc = [(YourApplicationDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];

Per comodità ho dichiarato definire per essa:

#define MOC [(YourApplicationDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]

Quindi, questo è diventato:

[MOC save:&error];

Si può prendere ovunque ti piace.Basta provare a guardare le auto codice generato per un CoreData applicazione in Xcode, vedrete che molte funzioni di accesso con CoreData sono lì, e il CoreData stesso pigramente inizializzato a prima richiesta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top