파일 래퍼를 사용하여 데이터를 저장하고로드하는 NSDocument 기반 응용 프로그램이 있습니다. 문서에 모든 종류의 리소스가있을 수 있으므로 모든 것을 메모리에로드하고 싶지는 않습니다. 나는 근본적으로 잘못된 것을하고 있을지 모르지만, 하나의 (내부) 파일을 변경하고 저장하면 바로 메모리에로드되지 않은 파일을 읽을 수 없습니다.NSFileWrapper, 지연로드 및 저장
이 문제를 재현하기 위해 관련 코드를 별도의 프로젝트로 구분했으며 동일한 결과를 얻었습니다. 기본 흐름은 다음과 같습니다.
- 디스크에서 기존 문서를로드합니다. 주 fileWrapper는 두 개의 다른 파일 래퍼 (sub1 및 sub2)가 포함 된 디렉토리 파일 래퍼입니다 (메인). 두 개의 내부 파일 래퍼는 이 아니고 현재이 아닙니다.
- 사용자가 하위 1을 편집하려고하면 디스크에서로드됩니다. 사용자가 다른 파일 (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 응답에서 본 것을 본 방식입니다. 문서가 디스크에서로드
- , 나는 애플의 문서가 NSFileWrapper 게으른 로딩을 지원하는 것을 말한다
(위의 코드에 myWrapper라고도 함) 내가 사용할 수 있도록 주위에 fileWrapper을 유지 증분 절약, 그래서 내 코드는 내가 볼 수없는 근본적인 결함이 있다고 가정합니다.
문서가 버전 관리를 지원합니까? –
나는 잘 모르겠다. 나는 그렇게 생각하지 않는다. 나는 그것을 지원하기 위해 아무것도하지 않았다. 그것은 아무것도 바꿀까요? 나중에 다시 살펴 보겠습니다. –
NSDocument 설정을 사용하면서 버전 관리를 지원하고있었습니다. 나는 끄기 위해 노력했지만 결과는 동일합니다 –