4 Stimmen

Wie man ein "temporäres" NSManagedObject ordnungsgemäß beim Beenden der Anwendung löscht

Ich erstelle ein temporäres NSManagedObject und verknüpfe es mit dem Haupt-NSManagedObjectContext. Ich muss es als voll funktionsfähiges Objekt behandeln können (Fetch-Anfragen durchführen usw.) innerhalb des Kontexts und daher kann ich es nicht ohne zugehörigen Kontext erstellen. Ich füge eine Logik ein, um das verwaltete Objekt in ViewWillDisappear zu löschen unter der Bedingung, dass nicht gerade ein neuer Ansichtscontroller auf den Stapel geschoben wurde:

- (void)viewWillDisappear:(BOOL)animated { 
  [super viewWillDisappear:animated];

  NSArray *viewControllers = self.navigationController.viewControllers;
  if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
    // Ansicht verschwindet, weil ein neuer Ansichtscontroller auf den Stapel geschoben wurde
  } else  {
    // Ansicht verschwindet aus einem anderen Grund
    [self.community.managedObjectContext deleteObject:self.community];
  }
}

Dies scheint das verwaltete Objekt in allen Fällen ordnungsgemäß zu löschen, außer wenn die Anwendung beendet wird. Ich habe versucht, das Objekt in viewDidUnload zu löschen, aber anscheinend wird die Methode nicht aufgerufen, wenn die Anwendung beendet wird. Ich habe darüber nachgedacht, einen zweiten verwalteten Objektkontext zu erstellen, möchte aber den großen Overhead wenn möglich vermeiden.

Danke, Graham

1voto

Mats Stijlaart Punkte 4979

Behalten Sie das verwaltete Objekt in einer gemeinsam genutzten Instanz oder als Klassenvariable, damit es von mehreren Stellen in Ihrer Anwendung aus erreichbar ist als nur von der Klasse, von der aus Sie es behandeln.

Es gibt zwei Szenarien:

1) vor iOS 4.0
Wenn die applicationWillTerminate aufgerufen wird, können Sie das Objekt aus dem Kontext löschen.

2) Seit iOS 4.0.
Wenn Ihre Anwendung in den Hintergrund wechselt und Sie den Prozess beenden (auf die harte Tour, mit der 'App-Beenden-Leiste'), wird die applicationWillTerminate niemals aufgerufen. Sie können dieses Ereignis nicht erkennen. Also sind Sie mit der applicationWillTerminate im Stich gelassen.
Sie müssen es folgendermaßen lösen:
- applicationWillEnterBackground: -> speichern Sie einen Bezeichner für das verwaltete Objekt in den Benutzereinstellungen oder einer einfachen Datei.
- applicationDidFinishLaunching: -> wenn die Datei vorhanden ist, löschen Sie das bezogene verwaltete Objekt.
- applicationWillEnterForeground: -> löschen Sie die Datei.

Jetzt, wenn Ihre App in den Hintergrund wechselt und zurückkommt, haben Sie denselben Zustand und das Objekt wird nicht gelöscht. Wenn Sie Ihre App beenden, wird das Objekt beim Start gelöscht.

0voto

Simon Goldeen Punkte 9030

In Ihrem App-Delegierten implementieren Sie die Methode -applicationWillTerminate:. Diese Methode wird kurz vor dem Entfernen Ihrer Anwendung aus dem Speicher aufgerufen und Sie können dort das temporäre verwaltete Objekt löschen.

0voto

amattn Punkte 9945

applicationWillTerminate und seine Multitasking-Verwandten funktionieren, aber da Sie nur ein einzelnes Objekt löschen, ist es am besten, Ihren Kontext nach jedem Löschen zu speichern.

Rufen Sie einfach - (BOOL)save:(NSError **)error auf:

[self.community.managedObjectContext deleteObject:self.community];
NSError *error = nil;
[self.community.managedObjectContext save:&error];

0voto

Jody Hagins Punkte 27786

Ich verstehe, dass Sie bereits eine funktionierende Antwort haben, aber wenn Ihr Objekt wirklich vorübergehend ist und nie gespeichert wird, warum erstellen Sie es nicht einfach in einem untergeordneten Kontext? Es wird immer noch die Abrufbarkeit haben, die Sie wünschen, aber wird nie in die anderen Kontexte verschoben oder in der physischen Datenbank gespeichert, bis Sie im Kontext speichern.

Wenn Sie nie speichern, wird das vorübergehende Objekt nie gespeichert und ist daher wirklich vorübergehend.

Und das Beste daran... Sie müssen überhaupt keinen zusätzlichen Code schreiben oder alle "Ausstiegsbedingungen" behandeln, da es nie in die eigentliche Datenbank eingefügt wurde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X