为什么会自动调用[UIDocument revertToContentsofURL:]?

时间:2014-10-02 17:31:20

标签: ios uikit uidocument

我有一个名为Song的UIDocument子类,用于在本地存储用户的内容。我使用UIDocument的主要原因是自动保存功能。

我遇到一个问题,即在对文档进行自动保存后,会调用-[Song revertToContentsOfURL:]。这会导致文档再次从磁盘加载。数据是最新的,但其他属性会重置,因为我的应用程序认为我正在打开一个新文档。我可以使用一个标志来检查文档是否已经打开而不是重置相关属性,但我宁愿阻止revertToContentsOfURL:首先被调用。

注意:这并不总是发生。似乎在首次启动应用程序时创建新文档时,它将在每次自动保存后调用revertToContentsOfURL:,但在后续运行中,自动保存将按预期执行。这可能只是巧合。

以下是相关代码:

Song.h

typedef NS_OPTIONS(NSUInteger, ChangeFlag) {
    ChangeFlagNone        = 0,

    ChangeFlagPaths       = 1 << 0,
    ChangeFlagInstruments = 1 << 1,
    ChangeFlagColors      = 1 << 2,
    ChangeFlagProperites  = 1 << 3,
    ChangeFlagMixer       = 1 << 4,
    ChangeFlagTools       = 1 << 5,
    ChangeFlagScreenshot  = 1 << 6,

    ChangeFlagAll = ~ChangeFlagNone
};

@interface Song : UIDocument

@property (nonatomic) ChangeFlag changes;

- (void)addChange:(ChangeFlag)change;
- (void)removeChange:(ChangeFlag)change;

@end

Song.m

#import "Song.h"

@implementation Song

- (void)addChange:(ChangeFlag)change {
    self.changes |= change;
}

- (void)removeChange:(ChangeFlag)change {
    self.changes &= ~change;
}

- (void)setChanges:(ChangeFlag)changes
{
    _changes = changes;

    dispatch_async(dispatch_get_main_queue(), ^{
        if (_changes == ChangeFlagNone) {
            [self updateChangeCount:UIDocumentChangeCleared];
        } else {
            [self updateChangeCount:UIDocumentChangeDone];
        }
    });
}

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    // populate various app properties
    // -[Song addChange:] will be called multiple times
    // ...

    // clear changes (called directly instead of through setChange to avoid async)
    _changes = ChangeFlagNone;
    [self updateChangeCount:UIDocumentChangeCleared];

    return YES;
}

- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    NSFileWrapper *rootDirectory = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];

    // store current changes value before clearing
    ChangeFlag changes = _changes;

    // clear changes (called directly instead of through setChange to avoid async)
    _changes = ChangeFlagNone;
    [self updateChangeCount:UIDocumentChangeCleared];

    // update various file wrappers in rootDirectory, based on flags in `changes` variable
    // ...

    return self.rootDirectory;
}

@end

0 个答案:

没有答案