我有一个基于NSDocument的应用程序使用filewrappers来保存和加载其数据。 该文件可以有各种资源,所以我不想将所有内容加载到内存中。我可能会做一些根本性错误的事情,但只要我更改一个(内部)文件然后保存,我就无法读取任何尚未加载到内存中的文件。NSFileWrapper,延迟加载和保存
我已将相关代码分隔到单独的项目中以重现此行为,并且获得了相同的结果。基本流程是这样的:
- 我从磁盘加载一个现有的文件。主fileWrapper是一个包含两个其他文件包装器(sub1和sub2)的目录文件打包程序(我将称之为main)。这两个内部文件包装是而不是在这一点上加载。
- 当用户想要编辑sub1时,它从磁盘加载。如果用户希望编辑其他文件(SUB2)
- 的用户保存文档
,它不能加载。出现的错误:
-[NSFileWrapper regularFileContents] tried to read the file wrapper's contents lazily but an error occurred: The file couldn’t be opened because it doesn’t exist.
这里是我的项目的相关代码:
此代码可能会更容易在这个要点如下: https://gist.github.com/bob-codingdutchmen/6869871
#define FileName01 @"testfile1.txt"
#define FileName02 @"testfile2.txt"
/**
* Only called when initializing a NEW document
*/
-(id)initWithType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
self = [self init];
if (self) {
self.myWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
NSLog(@"Initializing new document...");
NSString *testString1 = @"Lorem ipsum first sub file";
NSString *testString2 = @"This is the second sub file with completely unrelated contents";
NSFileWrapper *w1 = [[NSFileWrapper alloc] initRegularFileWithContents:[testString1 dataUsingEncoding:NSUTF8StringEncoding]];
NSFileWrapper *w2 = [[NSFileWrapper alloc] initRegularFileWithContents:[testString2 dataUsingEncoding:NSUTF8StringEncoding]];
w1.preferredFilename = FileName01;
w2.preferredFilename = FileName02;
[self.myWrapper addFileWrapper:w1];
[self.myWrapper addFileWrapper:w2];
}
return self;
}
-(NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
// This obviously wouldn't happen here normally, but it illustrates
// how the contents of the first file would be replaced
NSFileWrapper *w1 = [self.myWrapper.fileWrappers objectForKey:FileName01];
[self.myWrapper removeFileWrapper:w1];
NSFileWrapper *new1 = [[NSFileWrapper alloc] initRegularFileWithContents:[@"New file contents" dataUsingEncoding:NSUTF8StringEncoding]];
new1.preferredFilename = FileName01;
[self.myWrapper addFileWrapper:new1];
return self.myWrapper;
}
-(BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
self.myWrapper = fileWrapper;
return YES;
}
- (IBAction)button1Pressed:(id)sender {
// Read from file1 and show result in field1
NSFileWrapper *w1 = [[self.myWrapper fileWrappers] objectForKey:FileName01];
NSString *string1 = [[NSString alloc] initWithData:w1.regularFileContents encoding:NSUTF8StringEncoding];
[self.field1 setStringValue:string1];
}
- (IBAction)button2Pressed:(id)sender {
// Read from file2 and show result in field2
NSFileWrapper *w2 = [[self.myWrapper fileWrappers] objectForKey:FileName02];
NSString *string2 = [[NSString alloc] initWithData:w2.regularFileContents encoding:NSUTF8StringEncoding];
[self.field2 setStringValue:string2];
}
最下面两个方法仅用于更新UI,以便我可以看到会发生什么。
要更改文件的内容,我删除现有的fileWrapper并添加一个新的文件夹。这是我发现改变文件内容的唯一方法,以及我在其他SO答案中看到它完成的方式。
当文档被从磁盘加载,我把fileWrapper身边,所以我可以用它(被称为myWrapper在上面的代码)
苹果的文档说NSFileWrapper支持延迟加载和增量保存,所以我假设我的代码有一些我看不到的基本缺陷。
您的文档是否支持版本控制? – 2013-10-07 15:45:35
我不确定,所以我认为不是:)我没有做任何事情来支持它。它会改变什么吗?我将在以后看看 –
由于我使用NSDocument设置,因此我支持版本控制。我试过把它关掉,但结果是一样的 –