電子メール アドレスに関する情報を格納する別のエンティティと 1 対多の関係を持つ Contact エンティティがあります (個人、仕事などの電子メールの種類も含まれるため、TypedValue と呼ばれます)。
この関係 (当然「メール」と呼ばれます) も順序付けられているため、連絡先のメール アドレスのリストを表形式で表示し、ユーザーが各メール アドレスを削除または変更できるようにします。私が知る限り、どれが削除/変更されているかを確認できるように、それらを並べ替える必要があります。たとえば、ユーザーが行 1 の削除ボタンをタップした場合、2 番目の電子メール アドレスは関係から削除する必要があります。命令されなければ、どれを削除すればよいかわかりません。
NSManagedObject サブクラスを生成するときに、クラスで NSOrderedSet プロパティを取得し、CoreData が .h ファイルでいくつかのアクセサーを提供してくれました。
@interface Contact (CoreDataGeneratedAccessors)
- (void)insertObject:(TypedValue *)value inEmailsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromEmailsAtIndex:(NSUInteger)idx;
- (void)insertEmails:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeEmailsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInEmailsAtIndex:(NSUInteger)idx withObject:(TypedValue *)value;
- (void)replaceEmailsAtIndexes:(NSIndexSet *)indexes withEmails:(NSArray *)values;
- (void)addEmailsObject:(TypedValue *)value;
- (void)removeEmailsObject:(TypedValue *)value;
- (void)addEmails:(NSOrderedSet *)values;
- (void)removeEmails:(NSOrderedSet *)values;
@end
私の問題は、これらの一部しか機能しないことです。addEmailsObject:
正常に動作しますが、remove または replace メソッドは動作しません。セット内のオブジェクトの 1 つをこの呼び出しで置き換えようとすると、次のようになります。
// newVal is a properly-built object requested from the managed object context
[self replaceObjectInEmailsAtIndex:index withObject:newVal];
厄介なエラーが発生します:
2013-08-16 16:51:19.687 AppName[43837:c07] -[Contact replaceObjectInEmailsAtIndex:withObject:]: 認識されないセレクターがインスタンス 0xa56a800 に送信されました 2013-08-16 16:51:19.694 AppName[43837:c07] *アプリの終了キャッチされない例外 'NSInvalidArgumentException' のため、理由: '-[Contact replaceObjectInEmailsAtIndex:withObject:]: 認識されないセレクターがインスタンス 0xa56a800 に送信されました'
私が読んだことから、これは、呼び出しを行うオブジェクト (この場合は Contact オブジェクト) が、管理対象オブジェクトのコンテキストから要求されるのではなく、通常の alloc/init を使用して作成された場合に発生する可能性がありますが、その部分を正しく実行しています.
また、NSOrderedSet オブジェクトの変更可能なコピーを取得して、更新を行い、セットを置き換えようとしました。
NSMutableOrderedSet *newSet = [self.emails mutableCopy];
[newSet replaceObjectAtIndex:index withObject:newVal];
[self setEmails:newSet];
これはエラーをスローしませんでしたが、何かおかしなことをしました: 私のインターフェースは間違った値を表示し始め、何が起こったのか分かりません.
では、CoreData が提供すると主張するミューテーターを使用しない場合、オブジェクトを置き換えて削除する正しい方法は何でしょうか?