2014-02-26 1 views
1

문서 유형이 파일 묶음을 포함하는 패키지 번들 인 NSDocument 기반 응용 프로그램에서 작업하고 있습니다. 나는 따라서 절약 해요 :왜 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; 
} 

을 즉, 번들로, 폴더 "기본"을 만들고, 어떤 내용으로로 "someFile.ext"를 저장합니다.

이제 문제가 발생했습니다. 실제로 디스크에 저장되어 있는지 살펴 갈 때, 나는이를 참조하십시오

screenshot

내가 파일을 저장할 때마다 NSDocument 랩퍼는 자원의 일부 버전 복사본을 만들 것으로 보인다. 나는 버전이 지정된 복제본을 원하지 않으며 최신 내용의 바닐라 파일 만 원합니다.

버전이 지정된 리소스는 어디에서 제공 되나요? 무슨 일 이니? 읽어야 할 의사가 있습니까?

+0

'+ (BOOL) preservesVersions' 반환 값 NSDocument의 수신 서브 클래스 버전을 지원하는 경우 YES; 그렇지 않으면 아니오. –

+0

글쎄, 적어도 + (BOOL) preservesVersions가 NO를 반환 할 때, + (BOOL) autosavesInPlace가 반환하는 것에 상관없이 당신이리스트하는 여분의 파일의 존재를 확인할 수 있습니다. 이 두 함수의 반환 값을 변경하면 메뉴의 활성화 된 옵션에 영향을 미치므로 쿼리되지 않습니다. 다른 것을 찾으면 알려 드리겠습니다. – Erhannis

답변

2

좋아, 내가 알아 냈다고 생각해. 실제로 버전 관리 문제는 아니 었습니다. 매번 새로운 파일을 추가하는 것 같습니다. 첫째, 몇 가지 메모.

  1. 패키지에 파일을 만들지 않고 패키지에 '파일이 들어있는 디렉토리'라는 것을 표시합니다. 그게 네가하려는 의도 야?
  2. "default"디렉토리가 없으면 "someFile.ext"디렉토리를 만들고 사용합니다. 즉, 다음 번에 이상한 접두사가있는 새 디렉토리를 만드는 것입니다. 그러나 귀하의 스크린 샷에서 이미 "기본"디렉토리가 있다는 것을 알았습니다. 이는 귀하의 문제가 아님을 의미합니다.

지금, 실제 문제는 : 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; 
} 
  1. 나는, "기본"이기 위하여 defaultWrapper의 원하는 파일 이름을 변경했습니다.
  2. 이전에 저장 한 파일 (있는 경우)을 제거하는 블록을 if 추가했습니다.
  3. 다음 번 # 2에서 사용하기 위해 새로운 NSFileWrapper의 파일 이름을 저장했습니다.

이 변경 사항을 적용한 후 프로그램은 여러 번 저장 한 후에도 하나의 파일을 포함하는 하나의 디렉토리가 예상 한 동작이라고 생각합니다. preservesVersionsYES을 반환 한 경우에도 마찬가지입니다.버전을 저장하는 위치가 확실하지 않지만 볼 수는 없습니다.

+0

처음에는 "매번 새로운 파일을 추가하는 것 같습니다."라고 말했듯이 정확합니다. 그래서 이것은 제 마지막에 상당히 간단한 버그였습니다. 나는 같은 이름의 파일을 추가하는 것이 그것을 덮어 씌웠다 고 생각했지만 분명히 그렇지 않았다. 그래서 나는 스스로 복제본을 제거해야한다./"패키지에 파일을 생성하는 것이 아니라 패키지에 '파일을 포함하는 디렉토리'를 생성하는 것으로 나타납니다. 그것이 당신이 의도 한 것입니까? "- 네. – Jaanus

1

똑바로 -writeToURL까지 호출하도록 당신은 ... -writeSafely 구현할 수 : 이 -writeToURL을 구현 ... : ... 그것은 -fileWrapperOfType 호출하도록 : 다음 ... 그리고 글을 그 URL 원자

밖으로 즉, NSFileWrapper로 하여금 원자 저장에 대한 책임을 맡을 수 있습니다. 그런 식으로 래퍼는 파일이 실제로 어디에서 끝나는지 깔끔하게 추적해야합니다.

Source

관련 문제