47

CoreDataBooksバックグラウンドでセカンダリ管理オブジェクト コンテキストにデータを取り込み、そのデータをプライマリ管理オブジェクト コンテキストにマージするための基礎として、Apple のサンプル アプリケーションを使用しています。

私が引き込んでいるデータは、エンティティ (「所有者」と呼ばれる) とBookの対 1 関係を持つエンティティです。エンティティは(「本」と呼ばれる) と対多OwnerOwner関係にあります。Book

私のデータは、次の形式の XML ドキュメントです。

<Owner>
  <Name>alexpreynolds</Name>
  <ID>123456</ID>
</Owner>
<Books>
  <Book>Book One</Book>
  <Book>Book Two</Book>
  ...   
  <Book>Book N</Book>
</Books>

Book One~は 1 つ( )Book Nに関連付けられています。Owner"alexpreynolds, 123456"

OwnerこれをインスタンスとインスタンスでNSMutableSet構成されたものに解析していBookます。

初めて保存しようとすると、問題なく保存され、マージされたデータがテーブル ビューに表示されます。

ただし、2 回目の保存では、XML コンテンツに新しい本が含まれていると、機能しません。

何が起こるかは次のとおりです。

Book次に、まだプライマリ管理対象オブジェクト コンテキストにない新しい を含む XML ドキュメントをロードしようとしました。新しいは、他の に関連付けられているものとBook同じものを使用しています。OwnerBook

Ownerこの一意の管理オブジェクト (プライマリ管理オブジェクト コンテキストに既にある) と、プライマリ MOC にBookない一意のオブジェクトを選択するルーチンがあります。

これからBook、セカンダリ MOC に新しいオブジェクトを作成し、その " " 関係をプライマリ MOC で見つけownerた一意のものを指すように設定します。Owner

保存すると、次のエラーが表示されます。

*** Terminating app due to uncaught 
exception 'NSInvalidArgumentException', 
reason: 'Illegal attempt to establish a 
relationship 'owner' between objects in 
different contexts 

(source = <Book: 0x7803590> 
(entity: Book; id: 0x7802ae0 <x-coredata:///
Book/t527F06B2-3EB5-47CF-9A29-985B0D3758862>
; data: {
creationDate = 2009-10-12 06:01:53 -0700;
name = nil;
nameInitial = nil;
operations = (
);
owner = nil;
type = 0;
}) , 

destination = <Owner: 0x78020a0> (entity: 
Owner; id: 0x3a56f80 <x-coredata://043AF2F0-1AD0-
4078-A5E8-E9D7071D67D1/Owner/p1> ; data: {
books = "<relationship fault: 0x7801bf0 'books'>";
displayName = alexpreynolds;
ownerID = 123456;
}))'

Bookセカンダリ MOC に新しいエンティティを作成して、プライマリ MOC の既存のエンティティと引き続き関連付けることができるようにするにはどうすればよいOwnerですか?

4

6 に答える 6

72

異なる管理対象オブジェクト コンテキスト内のオブジェクト間に関係を持つことはできません。したがって、これを回避する 1 つの方法は、オブジェクトを管理オブジェクト コンテキストに持ち込むことです。

例えば:

NSManagedObject *book = // get a book in one MOC
NSManagedObject *owner = // get an owner in a different MOC
[[owner mutableSetValueForKey:@"books"] addObject:[owner.managedObjectContext objectWithID:[book objectID]]];

つまり、実際にはBookを と同じ管理対象オブジェクト コンテキストにフェッチしていますowner。ただし、これはbookすでに保存されている場合にのみ可能であることに注意してください。管理対象オブジェクト コンテキストは永続ストア内のオブジェクトを検索するため、最初に保存する必要があります。

于 2009-10-12T14:35:55.297 に答える
11

私は同じ問題を抱えていましたが、この文はエラーを解決するのに役立ちました.

異なる管理対象オブジェクト コンテキスト内のオブジェクト間に関係を持つことはできません。したがって、これを回避する 1 つの方法は、オブジェクトを管理オブジェクト コンテキストに持ち込むことです。

これが私のコードです(変数を置き換えて、機能するようにしました):

// Have the owner object and get the managedObjectContext
Owner *owner = [[DataFunctions alloc] getCurrentOwner];
NSManagedObjectContext *context = [owner managedObjectContext]; 

// Create a book and use the manageObjectContext of owner
Book *book = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:context];
[newQuote setValue: "Book Title" forKey:@"title"];
[newQuote setOwner:owner];

これが役立つことを願っています:)

于 2013-02-25T18:46:14.707 に答える
4

ここでは、異なるコンテキストで取得/作成された 2 つのオブジェクト間の関係を確立しようとしています。コア データでは、そのような関係を確立することはできません。これを実現するには、objectID を持つ最初のオブジェクトのコンテキストを使用して、(関係を作成しようとしている) 2 番目のオブジェクトをフェッチする必要があります。これで、これら 2 つのオブジェクト間の関係を確立できるはずです。例えば:

MagicalRecord.saveWithBlock({[unowned self] (localContext: NSManagedObjectContext!) in

    let user = User.MR_createEntityInContext(localContext)!
    .....
    .....
}) //here local context stores data on end of block itself

MagicalRecord.saveWithBlock({[unowned self] (localContext: NSManagedObjectContext!) in

    let address = Address.MR_createEntityInContext(localContext)!
    .....
    .....
    let user = localContext.objectWithID(self.user!.objectID) as! User
    user.address = address
})

これがあなたを助けることを願っています!

于 2016-04-18T11:23:25.767 に答える
2

エラーが示すように、値が別のコンテキストで保持されている別のオブジェクトに設定されている1つのCoreDataオブジェクトに関係を持つことは許可されていません。これを回避する1つの方法は、新しいオブジェクトを保存してプライマリコンテキストにマージするまで待ってから、owner関係を適切に設定することです(両方のオブジェクトが同じコンテキストにあるため、問題はありません)。

于 2009-10-12T13:38:53.867 に答える
1
book *book = [mainContext ........]   //Get book from default context

NSManagedObjectID *objectId = [book objectID];

Book *tmpBook = [tmpContext objectWithID:objectId]; //Now book has the legal relationship
于 2016-04-18T07:25:28.083 に答える
1

迅速なバージョン...

context.insert(objectFromOtherContext)
于 2018-06-01T01:35:43.253 に答える