2010-09-04 2 views
11

Кто-нибудь знает, как перенести NSOperationQueue на диск между запусками приложений?Сохранение NSOperationQueue

+0

Не могли бы вы сообщить нам, чего вы пытаетесь достичь? Возможно, есть лучший способ решить вашу проблему, чем упорство NSOperationQueue. – hwaxxer

ответ

10

Невозможно сделать это. NSOperations - это действия, части исполняемого кода, которые невозможно полностью сохранить на диске.

Однако в вашем приложении вы должны знать, какие операции были добавлены в очередь. Либо использование подкласса, либо наличие некоторых метаданных. Затем вы сохранили метаданные, информацию о том, что должно быть сделано, по-своему. При запуске приложения действия, которые ранее находились в очереди, теперь могут быть восстановлены из загруженных метаданных.

На данный момент я ничего не могу вам дать, но я надеюсь, что это было уже полезно!

5

Я согласен с Max - нет общего способа сделать это. Обычно вы хотите сделать операции концептуально транзакционными и связанными с состояниями в конечной машине. Сохраняйте текущее состояние и любые другие соответствующие данные по каждому переходу состояния (то есть завершенную операцию), затем располагайте единый код, который заполняет NSOperationQueue соответствующими операциями, основанными на текущем состоянии. Вызовите этот же код из вашего UI-управляемого кода и перезапустите приложение.

Команда, с которой я работаю, уже некоторое время обсуждает общий способ сделать как можно больше (в идеале, как класс или фреймворк), но пока у нас еще очень мало.

4

Если у вас относительно простая очередь, без зависимостей между операциями, это должно быть довольно просто сделать, используя NSCoder.

Общий подход для этого будет выглядеть следующим образом:

  1. перебирать незавершенные элементы NSOperation в очереди с использованием NSOperationQueue операций собственности. Операции будут выполняться в том порядке, в котором они были добавлены в очередь, и вы захотите сохранить заказ.

  2. Ваш NSOperations должен быть подклассифицирован и реализован протокол NSCoding, так что каждая операция знает, как архивировать и распаковывать себя, используя NSArchiver. Вам будет необходимо определить, какие свойства нужно сериализовать, чтобы правильно восстановить состояние очереди. Если вы создали какие-либо межоперационные зависимости, ваша ответственность - как-то сохранить и восстановить эти отношения - и, по всей вероятности, если ваша очередь сложна таким образом, вы, возможно, не захотите это делать в первую очередь. Сериализуйте (архивируйте) операцию и сохраните ее в NSArray или используйте какую-либо другую структуру для сохранения порядка очередей.

  3. Архив NSArray, содержащий сериализованные операции в файл.

  4. Чтобы восстановить свою очередь, вы «разрхивируете» NSArray из файла, а затем перейдете в список операций, распакуйте каждый NSOperation и добавьте их в очередь относительно исходного заказа.
6

Очень легко, сначала убедитесь, что все ваши NSOperations принять протокол NSCoding и реализовать методы, чтобы сказать, какие поля они хотят, чтобы сохранить и восстановить:

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

Наконец, сериализуйте и десериализируйте свою очередь, когда захотите. Это сохранит его в хранилище на телефоне в файле Documents/data, если ваша очередь вызывается 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]); 
} 
Смежные вопросы