Domanda

Sto cercando di creare un'applicazione per iPhone in cui l'utente può aggiungere le voci.Quando si preme una nuova voce, una finestra popup che chiede di lui per alcune informazioni.Poi si può premere "Annulla" o "Salva" per eliminare i dati o salvarlo su disco.

Per il salvataggio, io sto usando il Core Data framework, che funziona abbastanza bene.Tuttavia, non posso ottenere il pulsante "Annulla" per il lavoro.Quando la finestra si apre, per chiedere informazioni, ho creato un nuovo oggetto in oggetto gestito contesto (MOC).Poi, quando l'utente preme annulla, io cerco di usare la NSUndoManager appartenenti alla MOC.

Anche io vorrei farlo utilizzando nidificati annulla gruppi, perché ci potrebbero essere i gruppi nidificati.

A prova di questo, ho scritto una semplice applicazione.L'applicazione è solo la "Finestra di applicazione" del modello con i Dati di Nucleo abilitato.Per il modello di Dati di base, ho deciso di creare un unico ente denominato "Ente" con attributo di tipo integer "x".Quindi, all'interno della applicationDidFinishLaunching, aggiungere questo codice:

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

  // Override point for customization after app launch    

  unsigned int x=arc4random()%1000;
  [self.managedObjectContext processPendingChanges];
  [self.managedObjectContext.undoManager beginUndoGrouping];

  NSManagedObject *entity=[NSEntityDescription insertNewObjectForEntityForName:@"Entity" 
                                                        inManagedObjectContext:self.managedObjectContext];
  [entity setValue:[NSNumber numberWithInt:x] forKey:@"x"];
  NSLog(@"Insert Value %d",x);

  [self.managedObjectContext processPendingChanges];
  [self.managedObjectContext.undoManager endUndoGrouping];
  [self.managedObjectContext.undoManager undoNestedGroup];

  NSFetchRequest *fetchRequest=[[NSFetchRequest alloc] init];
  NSEntityDescription *entityEntity=[NSEntityDescription entityForName:@"Entity"
                                                inManagedObjectContext:self.managedObjectContext];
  [fetchRequest setEntity:entityEntity];
  NSArray *result=[self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
  for(entity in result) {
    NSLog(@"FETCHED ENTITY %d",[[entity valueForKey:@"x"] intValue]);
  }

    [window makeKeyAndVisible];
}

L'idea è semplice.Provare a inserire una nuova Entità oggetto, si annulla, recuperare tutti gli oggetti di Entità in MOC e stamparle.Se tutto ha funzionato correttamente, non ci devono essere oggetti alla fine.

Tuttavia, ottengo questo output:

[Session started at 2010-02-20 13:41:49 -0800.]
2010-02-20 13:41:51.695 Untitledundotes[7373:20b] Insert Value 136
2010-02-20 13:41:51.715 Untitledundotes[7373:20b] FETCHED ENTITY 136

Come si può vedere, l'oggetto è presente in MOC dopo cerco di annullare la sua creazione.Eventuali suggerimenti per cosa sto facendo di sbagliato?

È stato utile?

Soluzione

Il problema è causato dal fatto che, a differenza di OS X, il contesto oggetto gestito iPhone non contiene un gestore di annullamento per impostazione predefinita. È necessario aggiungere esplicitamente uno.

Modificare il codice generato nel delegato app per la proprietà managedObjectContext a guardare in questo modo:

- (NSManagedObjectContext *) managedObjectContext {

    if (managedObjectContext != nil) {
        return managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        //add the following 3 lines of code
        NSUndoManager *undoManager = [[NSUndoManager alloc] init];
        [managedObjectContext setUndoManager:undoManager];
        [undoManager release];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }

    return managedObjectContext;

}

Dopo aver effettuato questo cambiamento, il messaggio di log 2 ° non è più stampato.

La speranza che aiuta ...

Dave

Altri suggerimenti

Ho provato Dave approccio, ma non ha funzionato per me.Ho finalmente trovato la soluzione di Apple esempio CoreDataBooks

Il trucco è quello di creare un nuovo contesto che condivide il coordinatore con l'App di contesto.Per annullare le modifiche non avete bisogno di fare una cosa del genere, basta ignorare il nuovo oggetto di contesto.Dal momento che si condivide il coordinatore, il risparmio rielabora i tuoi contesto.

Ecco la mia versione adattata, dove utilizzare un oggetto statico per la temp contesto per creare un nuovo ChannelMO oggetto.

//Gets a new ChannelMO that is part of the addingManagedContext
+(ChannelMO*) getNewChannelMO{

    // Create a new managed object context for the new channel -- set its persistent store coordinator to the same as that from the fetched results controller's context.
    NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
    addingManagedObjectContext = addingContext;

    [addingManagedObjectContext setPersistentStoreCoordinator:[[self getContext] persistentStoreCoordinator]];

    ChannelMO* aux = (ChannelMO *)[NSEntityDescription insertNewObjectForEntityForName:@"ChannelMO" inManagedObjectContext:addingManagedObjectContext];
    return aux;
}

+(void) saveAddingContext{
    NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
    [dnc addObserver:self selector:@selector(addControllerContextDidSave:) 
                name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];

    NSError *error;
    if (![addingManagedObjectContext save:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }
    [dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];

    // Release the adding managed object context.
    addingManagedObjectContext = nil;
}

Spero che aiuta

Gonso

Dovrebbe funzionare. Hai assegnato correttamente il gestore di annullamento al vostro managedObjectContext? Se avete giustamente fatto che, di default ha undo registrazione abilitata, e si dovrebbe essere pronti per partire. C'è un buon articolo su dati fondamentali qui . C'è un buon tutorial su dati di base e NSUndoManager qui . Speranza che aiuta.

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