2010-09-04 17 views
11

Kann jemand eine NSOperationQueue auf dem Datenträger zwischen den Anwendungsstarts persistieren?Persistent NSOperationQueue

+0

Können Sie uns wissen lassen, was Sie erreichen möchten? Vielleicht gibt es einen besseren Weg, um Ihr Problem zu lösen als die NSOperationQueue. – hwaxxer

Antwort

10

Es gibt keine Möglichkeit, dies zu tun. NSOperationen sind Aktionen, Teile von lauffähigem Code, die nicht generisch auf der Festplatte gespeichert werden können.

In Ihrer Anwendung sollten Sie jedoch wissen, welche Operationen Sie der Warteschlange hinzugefügt haben. Entweder mit einer Unterklasse oder mit einigen Metadaten. Sie würden dann die Metadaten, die Informationen darüber, was getan werden soll, auf eine benutzerdefinierte Weise speichern. Nach dem Start der Anwendung können die zuvor in der Warteschlange befindlichen Aktionen aus den geladenen Metadaten neu erstellt werden.

Es gibt kaum noch etwas, das ich dir im Moment geben kann, aber ich hoffe, dass es schon hilfreich war!

5

Ich stimme Max zu - es gibt keine generische Möglichkeit, dies zu tun. In der Regel möchten Sie Operationen konzeptionell transaktional und mit Zuständen in einer endlichen Zustandsmaschine verknüpfen. Behalten Sie den aktuellen Zustand und alle anderen geeigneten Daten für jeden Zustandsübergang bei (d. H. Abgeschlossene Operation), dann haben Sie einen einzelnen Codeabschnitt, der die NSOperationQueue mit geeigneten Operationen auf der Grundlage des aktuellen Zustands füllt. Rufen Sie denselben Code aus Ihrem UI-Code auf und starten Sie die App neu.

Das Team, mit dem ich arbeite, diskutiert seit einiger Zeit einen allgemeinen Weg, um so viel wie möglich davon zu machen (idealerweise als wiederverwendbare Klasse oder Rahmen), aber wir sind noch nicht sehr weit.

4

Wenn Sie eine relativ einfache Warteschlange haben und keine Abhängigkeiten zwischen den Vorgängen haben, sollte dies durch die Nutzung von NSCoder ziemlich einfach sein.

Der allgemeine Ansatz für diese wie folgt tun würde:

  1. Iterate durch die anhängigen NSOperation Elemente in der Warteschlange die NSOperationQueue mit Operationen Eigenschaft. Die Vorgänge werden in der Reihenfolge ausgeführt, in der sie zur Warteschlange hinzugefügt wurden, und Sie möchten die Reihenfolge beibehalten.

  2. Ihre NSOperationen sollten unterklassifiziert werden und das NSCoding-Protokoll implementieren, so dass jeder Vorgang weiß, wie er sich mit NSArchiver archiviert und entpackt. Es liegt an Ihnen festzulegen, welche Eigenschaften serialisiert werden müssen, um den Status Ihrer Warteschlange ordnungsgemäß wiederherzustellen. Wenn Sie Interoperabilitätsabhängigkeiten erstellt haben, liegt es in Ihrer Verantwortung, diese Beziehungen irgendwie zu speichern und wiederherzustellen. Wenn Ihre Warteschlange auf diese Weise komplex ist, möchten Sie dies möglicherweise gar nicht erst tun. Serialisieren (archivieren) Sie die Operation und speichern Sie sie in einem NSArray oder verwenden Sie eine andere Struktur, um die Reihenfolge der Warteschlangen beizubehalten.

  3. Archivieren Sie das NSArray, das die serialisierten Operationen enthält, in eine Datei.

  4. Um Ihre Warteschlange wiederherzustellen, "entarre" Sie das NSArray aus der Datei und durchläuft dann die Liste der Operationen, löscht jede NSOperation und fügt sie der Warteschlange relativ zur ursprünglichen Reihenfolge hinzu.
6

Sehr einfach, zuerst alle Ihre NSOperations stellen Sie sicher, das NSCoding Protokoll annehmen und implementieren die Methoden zu erzählen, welche Felder sie wollen speichern und wiederzugewinnen:

MyOperation.h

@interface MyOperation : NSOperation<NSCoding> 

MeineOperation.m

#pragma mark NSCoding 

#define kSomeKey  @"someKey" 

- (void) encodeWithCoder:(NSCoder *)encoder { 
    [encoder encodeObject:[self someKey] forKey:kSomeKey]; 
} 

- (id)initWithCoder:(NSCoder *)decoder { 

    if (self = [super init]) { 
     NSString *someKey = [decoder decodeObjectForKey:kSomeKey]; 
     [self setSomeKey:someKey]; 
    } 

    return self; 
} 

Schließlich serialisieren und deserialisieren Sie Ihre Warteschlange wann immer Sie wollen. Dies speichert es in dem Speicher auf dem Telefon in der Datei Documents/data, vorausgesetzt, Ihre Warteschlange heißt operations.

NSString * const dataPath = @"~/Documents/data"; 

// private 
- (void) serializeQueue { 
    NSArray* storedOperations = [[self operations] operations]; 

    [NSKeyedArchiver archiveRootObject:storedOperations toFile:[dataPath stringByExpandingTildeInPath]]; 
} 

// private 
- (void) deserializeQueue { 
    NSArray* storedOperations = [NSKeyedUnarchiver unarchiveObjectWithFile:[dataPath stringByExpandingTildeInPath]]; 

    NSLog(@"count of opeations: %lu", (unsigned long) [storedOperations count]); 
}