CoreDataのオブジェクトIDを扱う際に問題があります。私は便利のためにMagicalRecordを使用しています.3つのコンテキストがあります:プライベートキューの作業コンテキスト、UIの親キューコンテキストと作業コンテキストの親、およびメインコンテキストの親であるプライベートキュー保存コンテキスト。永続的なNSManagedObjectIDはあまり永久的ではありませんか?
私の目標は、作業環境でオブジェクトを作成し、永続ストアに保存し、objectID URLをNSUserDefaultsに保存してから、あとでobjectIDを使用してそのMOを取り出せるようにすることです。しかし、私が探しているのは、オブジェクトの永久IDを保存した後に変更されていることです。
以下のコンソール出力では、私が永久IDを要求した後に戻ってくる値が "F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p1"ですが、CDのすべてのオブジェクトをリストするとそこに唯一のオブジェクトIDは "F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2"です。 p1対p2、どうしたの?
コード:
NSManagedObjectContext *c = [NSManagedObjectContext MR_contextThatPushesChangesToDefaultContext];
[c performBlockAndWait:^{
NSArray *all = [CDBaseAccount MR_findAllInContext:c];
NSLog(@"count: %d", all.count);
NSLog(@"all accounts = %@", all);
CDBaseAccount *a = [CDBaseAccount MR_createInContext:c];
a.accountName = @"foo";
[c MR_saveNestedContexts];
NSLog(@"temp a.objectID = %@", a.objectID);
NSError *error;
if (![c obtainPermanentIDsForObjects:@[a] error:&error]) {
NSLog(@"perm id error: %@", error);
return;
}
NSLog(@"perm a.objectID = %@", a.objectID);
NSURL *u = a.objectID.URIRepresentation;
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *d = [NSManagedObjectContext MR_defaultContext];
NSArray *all = [CDBaseAccount MR_findAllInContext:d];
NSLog(@"count: %d", all.count);
NSLog(@"all accounts = %@", all);
NSManagedObjectID *i = [d.persistentStoreCoordinator managedObjectIDForURIRepresentation:u];
NSError *objWithIdError = nil;
NSManagedObject *o = [d existingObjectWithID:i error:&objWithIdError];
if (objWithIdError != nil) {
NSLog(@"existing object error: %@", objWithIdError);
return;
}
NSLog(@"o = %@", o);
NSLog(@"o.objectID = %@", o.objectID);
});
}];
コンソール出力:
> +[NSManagedObjectContext(MagicalRecord) MR_contextWithStoreCoordinator:](0xa7c9b0) -> Created <NSManagedObjectContext: 0x83522a0>: Context *** MAIN THREAD ***
> count: 0
> all accounts = (
>)
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x8353de0) -> Saving <NSManagedObjectContext: 0x8353de0>: Context *** MAIN THREAD ***
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x8195450) -> Saving <NSManagedObjectContext: 0x8195450>: *** DEFAULT *** Context *** MAIN THREAD ***
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x83522a0) -> Saving <NSManagedObjectContext: 0x83522a0>: *** BACKGROUND SAVE *** Context *** MAIN THREAD ***
> temp a.objectID = 0x8187ee0 <x-coredata:///CDBaseAccount/tF392AC6A-3539-4F39-AC53-35F9E5B3C9322>
> perm a.objectID = 0x8355800 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2>
> count: 1
> all accounts = (
"<CDBaseAccount: 0x844ca60> (entity: CDBaseAccount; id: 0x844a4c0 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p1> ; data: <fault>)"
)
> existing object error: Error Domain=NSCocoaErrorDomain Code=133000 "The operation couldn’t be completed. (Cocoa error 133000.)" UserInfo=0x864d8c0 {NSAffectedObjectsErrorKey=(
"<CDBaseAccount: 0x864b8c0> (entity: CDBaseAccount; id: 0x86405c0 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2> ; data: <fault>)"
)}
おかげで、そんなにマーカス!すべての文書で単語「永久」という言葉は本当に欺まれています。私はあなたのCDブックの新版を出してくれることを願っています。古いものはOOPですから。 – brianpartridge
+1の 'globallyUniqueString' –
アプリ起動時に' isTemporaryID'に 'NO'を返す' NSManagedObjectID'があれば間違いなくスケッチをしています。これは私のために非常にうまく動作し、長い間行ってきました。 –