2

概要:

  1. 自動生成された NSManagedObject サブクラスで提供される remove メソッドを使用して NSManagedObject を削除します
  2. 次に、データベースを保存しようとします
  3. データベースの保存に失敗しました。

.

 - (void)removeEmployees:(NSSet *)values; //Auto generated method in Department.h

ただし、 add メソッドを使用して NSManagedObject を追加すると、データベースを正常に保存できます

 - (void)addEmployeesObject:(Employee *)value; //Auto generated method in Department.h - works fine

注: XCode によって生成された NSManagedObject サブクラスを使用しています。

エンティティの詳細:

  • 「従業員」と「部門」という2つのテーブル(エンティティ)があります
  • 1 つの部門に複数の従業員を含めることができます
  • 1 人の従業員は 1 つの部門にのみ所属できます

関係の詳細:

  • 「従業員」から「部署」への関係は、1 対 1 の関係であり、「どの部署」と呼ばれます。削除ルールは無効化
  • 「部署」から「従業員」への関係は多対一の関係であり、「従業員」と呼ばれます。削除ルールはカスケードです

問題:

「Department」クラスには下記のようなメソッドがあり、このメソッドを使用するとデータベースの保存がうまくいきません

(void)removeEmployees:(NSSet *)values; //Auto generated method in Department.h //does not work

削除に使用されるコード:

- (void) removeEmployeesHavingAgeAsZeroWithDepartment: (Department*) department

{
    NSMutableSet *employeesSetToBeRemoved = [[NSMutableSet alloc] init];

    for(Employees *currentEmployee in department.employees)
    {
        if(currentEmployee.age == 0)
        {
            [employeesSetToBeRemoved addObject:currentEmployee];
        }
    }

    [department removeEmployees:employeesSetToBeRemoved]; //causing the problem
}

データベースの保存に使用されるコード

[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) 
  {NSLog(@"DB saved");}];

質問:

  1. remove メソッドを使用した後にデータベースを保存できないのはなぜですか?
  2. このメソッドを実装する必要がありますか? 現在、このメソッドの実装は見当たりません。ヘッダー ファイルでしか見つけることができません。
  3. リレーションシップ (逆、削除ルールなど) は正しく設定されていますか?

答え:

  • Jody の回答とコメント (5 月 17 日 4:39) を参照してください。問題をデバッグして根本原因を見つける方法についても説明されています。
4

2 に答える 2

4

コンテキストを保存していないに違いありません。オブジェクトを削除すると、次にコンテキストが保存されたときに削除されるようにマークされます。

これらのオブジェクトのそれぞれに対して isDeleted を呼び出すと、何が返されるでしょうか?

編集

ああ... UIManagedDocument を使用しているようです (使用している保存呼び出しでわかります)。特にCoreDataを扱う場合は、非常に多くのノブと相互作用があるため、質問に完全な詳細を提供する必要があります.

まず、UIManagedDocument は「セーブレス」アーキテクチャです。UIManangedDocument を使用する場合は、saveToURL の呼び出しに頼るべきではありません。

バックグラウンド スレッドに自動的に保存されます。ただし、変更する更新があることを伝えなければなりません。

また、それが保存されていないことをどのように知っていますか? 奇妙な質問のように聞こえるかもしれませんが、何を見ているのか、ドキュメントが保存されていないことをどのように判断しているのかを知ることが重要です。

ドキュメントには、保存する場合は、次の 2 つのいずれかを行う必要があると記載されています。

  1. UndoManager を使用して、ダーティ マークを付ける
  2. [ドキュメント updateChangeCount:UIDocumentChangeDone] を呼び出します。

現在、実際の保存は、将来の弱体化した時点で行われます。ただし、一部の操作 (バックグラウンドへの移行など) によって保存がトリガーされます。

繰り返しますが、データが保存されていないことはどのようにわかりますか?

ファイルを見て、MOC からフェッチして、管理対象オブジェクトを見ているだけですか?

追加

[self.database updateChangeCount:UIDocumentChangeDone];

その削除機能の最後に、あなたのデータは確実に保存されます。

編集

残念ながら、エラーが発生した場合、バックグラウンドでの保存は黙って失敗する可能性があります。したがって、ステータス変更通知を監視する必要があります。これは、獲得 sn エラーが発生したときに受け取る唯一の通知です。

エラーの結果としてステータスが変更されたときに通知を受け取りますが、エラーの原因に関する詳細はわかりません。それを取得するには、実際の NSError の詳細が必要な場合は、UIManagedDocument のサブクラスで handleError:userInteractionPermitted: をオーバーライドする必要があります。

ステータス変更通知を登録し、UIManagedDocument の単純なサブクラスに handleError:userInteractionPermitted: をオーバーライドしてエラーをログに記録します。それがあなたに言うことを見てください。うまくいけば、保存が行われない理由がわかるでしょう。

また、保存を待つ必要があることを忘れないでください。

最後に、CoreData が SQL レベルで何を行っているかを確認したい場合は、コマンド ライン オプションでデバッグ (-com.apple.CoreData.SQLDebug 1) を設定して、SQLLite ステートメントを表示します。

于 2012-05-15T15:41:45.790 に答える
2

調査の結果、データベースが保存されていないことに気付きました。

自動生成された削除メソッドを使用する代わりに、NSManagedObjectContextdeleteObjectメソッドを使用しました

修理:

[self.managedObjectContext deleteObject:currentEmployee];
于 2012-05-15T15:39:42.673 に答える