1

ドキュメント タイプが多数のファイルを含むパッケージ バンドルである 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 ラッパーがリソースのバージョン管理されたコピーを作成するようです。バージョン管理されたクローンは必要ありません。最新のコンテンツを含むバニラ ファイルのみが必要です。

バージョン管理されたリソースはどこから来るのですか? 何が起きてる?読むべきドキュメントはありますか?

4

2 に答える 2

2

わかりました、私はそれを理解したと思います。結局のところ、これは実際にはバージョン管理の問題ではありませんでした。毎回新しいファイルを追加しているだけのようです。まず、いくつかのメモ。

  1. パッケージ内のファイルではなく、パッケージ内の「ファイルを含むディレクトリ」を作成しているようです。それがあなたの意図したことですか?
  2. ディレクトリ「default」が存在しない場合は、ディレクトリ「someFile.ext」を作成して使用するようです。これは、次回、奇妙なプレフィックスを持つ新しいディレクトリを作成することを意味します。ただし、スクリーンショットから、既にディレクトリ「デフォルト」があることがわかります。これは、これが問題ではないことを意味します。

さて、あなたの実際の問題:このドキュメントによると、ディレクトリ( )に(基本的に)その名前のファイルが既に含まれていない限りaddRegularFileWithContents、好みのファイル名で新しいファイルを作成します。既に存在する場合は、プレフィックス付きの新しいファイルを作成します。 作成された NSFileWrapper を参照する識別文字列を返します (ファイル名だと思います)。defaultWrapperaddRegularFileWithContents

そのため、ファイルを保存するたびに、その名前のファイルが既に存在することがわかり、新しいプレフィックス付きのファイルが作成されます。これを解決する 1 つの方法は、 によって返された NSString を保持することです。次に、保存するときに、格納されている NSString に関連付けられている NSFileWrapperaddRegularFileWithContentsを確認して削除し、通常どおりにファイルを追加します。defaultWrapperコードを次のように変更しました。

@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 のファイル名を保存しました。

これらの変更の後、プログラムは、あなたが期待する動作であると私が思うものを示しました。複数回保存した後でも、1 つのファイルを含む 1 つのディレクトリです。preservesVersionsこれは返された場合でも当てはまることに注意してくださいYES。バージョンがどこに保存されているかはわかりませんが、見ませんでした。

于 2014-03-07T21:26:05.207 に答える
1

-writeSafely … を実装して、-writeToURL:… を直接呼び出すようにします。

つまり、NSFileWrapper にアトミック セーブを実行させることで、アトミック セーブの責任を引き継ぐことになります。そうすれば、ラッパーはファイルが実際にどこに到達するかをきちんと追跡する必要があります。

ソース

于 2014-03-09T20:30:04.887 に答える