简体   繁体   中英

Persisting NSOperationQueue

有没有人知道如何在应用程序启动之间将NSOperationQueue保留到磁盘?

There's no way to do so. NSOperations are actions, parts of runnable code, that are impossible to generically persist to disk.

However, in your application you should know what operations you added to the queue. Either by using a subclass or by having some metadata around. You'd then store the metadata, the information about what should be done, in a custom way. Upon application launch the actions that previously were in the queue can now be re-created from the loaded metadata.

There is hardly anything else I can give you at the moment, but I hope that was helpful already!

Very easy, first make sure all of your NSOperations adopt the NSCoding protocol, and implement the methods to tell which fields they want to save and regain:

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

Finally, serialize and deserialize your queue whenever you want. This will store it to the storage on the phone in the Documents/data file, assuming your queue is called 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]);
}

I agree with Max - there isn't a generic way to do this. Typically you want to make operations conceptually transactional and associated with states in a finite state machine. Persist the current state and any other appropriate data on each state transition (ie completed operation) then have a single piece of code which fills the NSOperationQueue with appropriate operations based on the current state. Invoke this same code from your UI-driven code and on restarting the app.

The team I work with have been discussing for some time a generic way to do as much of this as possible (ideally as a reusable class or framework), but we haven't got very far as yet.

If you have a relatively simple queue, with no dependencies between operations, this should be pretty straightforward to do by leveraging NSCoder.

The general approach for doing this would be as follows:

  1. Iterate through the pending NSOperation items in the queue using the NSOperationQueue operations property. The operations will be in the order they were added to the queue and you'll want to preserve the ordering.

  2. Your NSOperations should be sub-classed and implementing the NSCoding protocol, so that each operation knows how to archive and unarchive itself using NSArchiver. It will be up to you to determine what properties need to be serialized in order to properly restore the state of your queue. If you have created any inter-operation dependencies, it will be your responsibility to somehow save and restore those relationships - and in all likelihood, if your queue is complex in that way, you might not want to be doing this in the first place. Serialize (archive) the operation, and store it to an NSArray or use some other structure to preserve queue order.

  3. Archive the NSArray containing the serialized operations to a file.

  4. To restore your queue, you'll "unarchive" the NSArray from the file, and then iterate through the list of operations, unarchiving each NSOperation, and adding it to the queue relative to the original ordering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM