我有一个名为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