简体   繁体   English

坚持NSOperationQueue

[英]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. NSOperations是动作,可运行代码的一部分,一般不可能持久存储到磁盘。

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: 非常简单,首先要确保所有的NSOperations都采用NSCoding协议,并实现方法来告诉他们想要保存哪些字段并重新获得:

MyOperation.h MyOperation.h

@interface MyOperation : NSOperation<NSCoding>

MyOperation.m 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 . 这将把它存储在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]);
}

I agree with Max - there isn't a generic way to do this. 我同意Max - 没有通用的方法来做到这一点。 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. 在每个状态转换(即完成的操作)上保持当前状态和任何其他适当的数据然后具有单个代码,其基于当前状态用适当的操作填充NSOperationQueue。 Invoke this same code from your UI-driven code and on restarting the app. 从UI驱动的代码和重新启动应用程序调用相同的代码。

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. 如果你有一个相对简单的队列,在操作之间没有依赖关系,那么通过利用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. 使用NSOperationQueue 操作属性迭代队列中的待处理NSOperation项。 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. 您的NSOperations应该是子类并实现NSCoding协议,以便每个操作都知道如何使用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. 序列化(存档)操作,并将其存储到NSArray或使用其他一些结构来保留队列顺序。

  3. Archive the NSArray containing the serialized operations to a file. 将包含序列化操作的NSArray存档到文件中。

  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. 要恢复队列,您将从文件中“取消归档”NSArray,然后遍历操作列表,取消归档每个NSOperation,并将其添加到相对于原始排序的队列中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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