0

UIManagedDocument にはさらにヘルプがあり、UIDocument のサブクラスであるため、UIDocument と UIManagedDocument についてここでできることはすべて読んできましたが、これについて何をする必要があるかわかりませんでした。

ユーザーが新しいドキュメントを作成するためにアプリの追加ボタンを押すと、ドキュメントを作成し、いくつかのアイテムを事前入力する必要があります。これを実行するためのコードは、デバッガーを 1 ステップ実行している限り問題なく動作しますが、全速力で実行すると、いくつかの項目がドキュメントに表示されません。

ドキュメントへの参照を AppDelegate に保存し、コードを簡単に読み取れるようにマクロを定義します。

#define SelectedDocument [(AppDelegate *)[[UIApplication sharedApplication] delegate] selectedDocument]

したがって、追加リクエストを処理する際に、私のコードはこれを行います:

GnKDocument *tmp = [[GnKDocument alloc] initWithFileURL:fileURL];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setSelectedDocument:tmp];
[SelectedDocument saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
    if (success) {
        [SelectedDocument openWithCompletionHandler:^(BOOL success) {
            if (success) {
                [SelectedDocument setDateCreated:[NSDate date]];
                NSString *c1UUID = [SelectedDocument appendChapterWithName:@"Chapter 1"
                                                               withColor:kChapterColorYellow];
                NSString *p1c1UUID = [SelectedDocument appendPageWithParent:c1UUID
                                                                       withName:@"Page 1"
                                                                      withColor:kPageColorRed];
                NSLog(@"Just added Page 1 as %@ to chapter %@", p1c1UUID, c1UUID);
                [SelectedDocument closeWithCompletionHandler:^(BOOL success) {
                 }];
            }
     }
 }];

私の UIDocument サブクラスへの 2 つの追加呼び出しは、それぞれの作業を行ってから呼び出します

[self updateChangeCount:UIDocumentChangeDone];

そして、テストのステップとして、変更が行われていることをログアウトするためだけにそのメソッドをオーバーライドしました。

- (void)updateChangeCount:(UIDocumentChangeKind)change
{
     [super updateChangeCount:change];
     NSLog(@"GnKDocument recording a change");
}

私は正しい順序で物事を行っていますか?コールをさまざまなキューにディスパッチする必要がありますか?

  1. インスタンスを初期化する
  2. 作成するために保存します
  3. それを開きます(最初のアイテムを追加するため)
  4. 追加する
  5. それを閉じます(ドキュメントによると、 closeWithCompletionHandler: 非同期に変更を保存します)。

繰り返しますが、各呼び出し (saveToURL:、openWithCompletionHandler:、および closeWithCompletionHandler) にブレークポイントを設定し、それらの呼び出しを「ステップ オーバー」してから実行して完了ハンドラーに入る場合、ドキュメントは意図したとおりにディスクに配置されます。ブレークポイントを無効にして再度実行すると、ディスク上にドキュメントが作成され、変更がログに記録されますが、閉じたファイルには最初の 2 つの要素が含まれていません。

4

1 に答える 1

0

長い間、違いはコードの実行速度が競合状態を作成または回避していると考えていました。しかし、その可能性を調査する際に、重大なことが起こっているあらゆる場所に多くの NSLog ステートメントを追加しました...そして問題はなくなりました。したがって、明らかにタイミングの問題ではありませんでした。NSLog ステートメントの内容を振り返ってみると、一部の値が遅延ロードされていて、NSLog ステートメントでそれらを参照する行為が値のロードを引き起こしていることに気付きました。同様に、コードを 1 ステップ実行しているときに、「... の説明を印刷」コマンドが同じ効果を持っていたのではないかと思います (おそらく)。

したがって、私の場合、UIDocument サブクラスは、ドキュメントに関するメタデータ用のファイルと実際のドキュメント データ用の 2 つのファイルを含むファイル ラッパーを作成します。ドキュメントの最小限の正確性を検証するテストがありました。このテストでは、メタデータ ファイルの値を使用しました。この値は、遅延ロードされることを意図していましたが、アクセスされたことがないため、ファイルが有効ではないと判断され、すべての初期値が設定されました。もう一度、ファイルに事前入力していた 2 つの項目を消去します。

于 2012-09-19T03:58:49.887 に答える