我正在开发一个基于NSDocument的应用程序,其文档类型是包含一堆文件的包。我正在保存它:
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
if (!self.documentFileWrapper) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
if (!defaultWrapper) {
defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[defaultWrapper setPreferredFilename:@"someFile.ext"];
[self.documentFileWrapper addFileWrapper:defaultWrapper];
}
[defaultWrapper addRegularFileWithContents: ... some computed content for the file ... preferredFilename:@"someFile.ext"];
return self.documentFileWrapper;
}
换句话说,在包中创建一个文件夹“default”,并用一些内容将“someFile.ext”保存到其中。
现在,问题。当我查看实际保存在磁盘上的内容时,我看到了这一点:
每次保存文件时,NSDocument包装器似乎都会创建一些版本的资源副本。我不想要版本化的克隆,我只想要带有最新内容的vanilla文件。
版本化资源来自哪里?这里发生了什么?我应该阅读一份文件吗?
答案 0 :(得分:2)
好的,我想我已经明白了。事实证明,它实际上并不是版本问题。您似乎每次只是添加一个新文件。首先,请注意几点。
现在,您的实际问题:根据this documentation,addRegularFileWithContents
使用您首选的文件名创建一个新文件,除非目录(defaultWrapper
)已包含具有该名称的文件(基本上)。如果已经存在,则会创建带有前缀的新文件。 addRegularFileWithContents
返回一个引用创建的NSFileWrapper的标识字符串(我认为它是文件名)。
所以,正在发生的事情是,每次你去保存文件时,它都会看到已有一个该名称的文件,并创建一个新的前缀文件。解决此问题的一种方法是保留由addRegularFileWithContents
返回的NSString,然后当你去保存时检查defaultWrapper
并删除与存储的NSString相关联的NSFileWrapper(如果有的话),然后添加文件就像正常一样。我修改了你的代码如下:
@interface TestDocument () // Relevant part of my test class. Note `wrapperFileName`.
@property (nonatomic, strong) NSFileWrapper *documentFileWrapper;
@property (nonatomic, strong) NSString *wrapperFileName;
@end
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
if (!self.documentFileWrapper) {
NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[self setDocumentFileWrapper:documentFileWrapper];
}
NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
if (!defaultWrapper) {
defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
[defaultWrapper setPreferredFilename:@"default"];
[self.documentFileWrapper addFileWrapper:defaultWrapper];
} else if (self.wrapperFileName) {
[defaultWrapper removeFileWrapper:[[defaultWrapper fileWrappers] objectForKey:self.wrapperFileName]];
}
self.wrapperFileName = [defaultWrapper addRegularFileWithContents:[@"blah blah" dataUsingEncoding:NSUTF8StringEncoding] preferredFilename:@"someFile.txt"];
return self.documentFileWrapper;
}
defaultWrapper
的首选文件名更改为“默认”,因为我怀疑你的意图。if
块,删除以前保存的文件(如果存在)。在这些更改之后,程序演示了我认为您期望的行为:一个目录包含一个文件,即使在多次保存之后也是如此。请注意,即使preservesVersions
返回YES
,也是如此。我不确定它存储版本的位置,但我没有看到它们。
答案 1 :(得分:1)
您可以实现-writeSafely ...以便直接调用-writeToURL:... 实现-writeToURL:...以便它调用-fileWrapperOfType:...然后将其写入URL 原子
即。你可以通过让NSFileWrapper做到这一点来接管原子保存的责任。这样包装器应该整齐地跟踪文件最终的位置。