2010-09-04 20 views
11

¿Alguien sabe cómo persistir un NSOperationQueue en el disco entre los inicios de la aplicación?persistente NSOperationQueue

+0

¿Podría decirnos lo que está tratando de lograr? Tal vez haya una mejor manera de resolver su problema que persistir NSOperationQueue. – hwaxxer

Respuesta

10

No hay forma de hacerlo. Las NSOperations son acciones, partes del código ejecutable, que son imposibles de mantener genéricamente en el disco.

Sin embargo, en su aplicación debe saber qué operaciones ha agregado a la cola. Ya sea usando una subclase o teniendo algunos metadatos alrededor. A continuación, debe almacenar los metadatos, la información sobre lo que debe hacerse, de forma personalizada. Tras el inicio de la aplicación, las acciones que anteriormente estaban en la cola ahora se pueden volver a crear a partir de los metadatos cargados.

No hay casi nada más que pueda darte por el momento, ¡pero espero que ya haya sido útil!

5

Estoy de acuerdo con Max: no hay una forma genérica de hacerlo. Normalmente desea realizar operaciones conceptualmente transaccionales y asociadas con estados en una máquina de estados finitos. Persista el estado actual y cualquier otro dato apropiado en cada transición de estado (es decir, la operación completada) y luego tenga un único fragmento de código que llene el NSOperationQueue con las operaciones apropiadas en función del estado actual. Invoca este mismo código desde tu código de UI y al reiniciar la aplicación.

El equipo con el que trabajo ha estado discutiendo durante algún tiempo de forma genérica para hacer todo esto posible (idealmente como una clase o marco reutilizable), pero aún no hemos llegado muy lejos.

4

Si tiene una cola relativamente simple, sin dependencias entre las operaciones, esto debería ser bastante sencillo de hacer mediante el aprovechamiento de NSCoder.

El enfoque general para hacer esto sería la siguiente:

  1. Iterar a través de los artículos pendientes NSOperation en la cola utilizando el NSOperationQueue operaciones propiedad. Las operaciones se realizarán en el orden en que se agregaron a la cola y usted querrá conservar el orden.

  2. Sus NSOperaciones deben ser sub-clasificadas e implementando el protocolo NSCoding, para que cada operación sepa cómo archivar y desarchivar usando NSArchiver. Depende de usted determinar qué propiedades necesitan ser serializadas para restaurar adecuadamente el estado de su cola. Si ha creado dependencias entre operaciones, será su responsabilidad de alguna manera guardar y restaurar esas relaciones, y con toda probabilidad, si su cola es compleja de esa manera, es posible que no desee hacer esto en primer lugar. Serializar (archivar) la operación y almacenarla en un NSArray o usar alguna otra estructura para conservar el orden de la cola.

  3. Archive el NSArray que contiene las operaciones serializadas en un archivo.

  4. Para restaurar la cola, "desarchivará" el NSArray del archivo, y luego recorrerá la lista de operaciones, desarchivará cada NSOperation y lo agregará a la cola en relación con el orden original.
6

Muy fácil, primero asegúrese de que todas sus NSOperations adoptar el protocolo NSCoding, y poner en práctica los métodos de decir qué campos quieren salvar y recuperar:

MyOperation.h

@interface MyOperation : NSOperation<NSCoding> 

MyOperation.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; 
} 

Finalmente, serialice y deserialice su cola siempre que lo desee. Esto lo almacenará en el almacenamiento en el teléfono en el archivo Documents/data, asumiendo que su cola se llame 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]); 
}