10

s を使用してデータを保存するUIDocumentベースのアプリがあります。NSFileWrapper「マスター」ファイル ラッパーには、多くの追加のディレクトリ ファイル ラッパーが含まれており、それぞれがドキュメントの異なるページを表します。

1 ページのごく一部しか変更されていない大きなドキュメントを保存する場合、UIDocumentはバックグラウンドで変更を書き込むのに長い時間を費やします ( をwriteContents:andAttributes:safelyToURL:forSaveOperation:error:参照)。確かに、ファイル ラッパーへのこの 1 つの小さな変更を書き出すだけのはずです...何がそんなに時間がかかっているのでしょうか?

私のcontentsForType:error:オーバーライドは、マスター ファイル ラッパーの内容を含む新しいディレクトリ ファイル ラッパーを返します ( WWDC 2012 セッション 218 - Using iCloud with UIDocument ):

- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    if (!_fileWrapper) {
        [self setupEmptyDocument];
    }
    return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[_fileWrapper fileWrappers]];
}

Time Profiler からのスタック トレースの素敵な写真を次に示します。

UIDocument 書き込みの遅いスタック トレース

ちなみに、そのワーカースレッドで保存するのに〜1.6秒と表示されています-実際の実行時間では、これは約8秒に相当します。


編集:

ファイルラッパーがディスクへの書き込みを必要とするかどうかを確認する方法はありますか? 小さな変更を加えたときにすべてのサブファイルラッパーを更新するなど、何らかの奇妙なことをしていないことを確認できるようにします(そうではないと確信していますが...)。


編集:

CloudNotes サンプル アプリをさらに試してみたところ、少なくともその場合は増分保存NSFileWrapper が実装されているようです! それぞれ約 5MB のデータを含む 100 のメモを含むドキュメントを初期化してテストしました。あちこちで小さな編集を行い (テキスト ビューに 1 文字変更すると、文書に保存が必要であるというフラグが付けられます)、各保存にかかった時間を大まかに記録しました。テストは比較的粗雑です (シミュレーターで実行します) が、結果は次のようになりました。

  • 最初の書き込み: ~8000ms
  • 2 回目の書き込み: ~4000ms
  • 3 回目の書き込み: ~300ms
  • 後続のすべての書き込み: ~40ms

特にバックグラウンド スレッドでファイル調整を使用して保存しているため、所要時間に影響を与える多くの要因があることは明らかですが、一般的には、すべての書き込みが非常に高速になるまで、この種の指数関数的な減衰が常に見られます。

しかし、なぜこれが私のアプリで起こらないのかを理解しようとしています。大きな複数ページのドキュメント (大きいが、上記で実行した CloudNotes テストのドキュメントよりも何倍も小さい) の場合、ユーザーはドキュメントが閉じるまで何秒も待つことができます。実質的に瞬間的なもののためにスピナーを設置する必要はありません。

4

2 に答える 2