3

CoreData と Parent-Child MOC に関するこの問題で立ち往生しています。オブジェクトを子 MOC に追加し、それらを保存し、親 MOC を保存すると、すべてのオブジェクトの属性が defaultValue にリセットされます。

2 つの MOC からのログをここに貼り付けました。具体的には、これらのログでリセットされる「stringAttribute」属性と「date」属性です。

どこでもこの問題を検索しましたが、何も見つかりませんでした。また、親子MOCの多くの実装を見ましたが、何が間違っているのかわかりません。

前もって感謝します!

コード スニペットは次のとおりです。

NSManagedObject をメイン コンテキストに追加し、saveContext:メソッドで保存します。

// Another singleton method
- (void)anotherMethod
{
   [...]
   [self.managedObjectContext insertObject:managedObject];
   NSError *error;
   save = [self saveContext:&error];
   [...]
}

// Database manager singleton method

- (BOOL)saveContext:(DKError *__autoreleasing *)error
{

    __block BOOL save = NO;
    __block NSError *internalError;

    [self.managedObjectContext performBlockAndWait:^{
        internalError = nil;

        [self.managedObjectContext log]; // See log 1.1 below

        save = [self.managedObjectContext save:&internalError];
        if (!save) {
            NSLog(@"Error saving data in main context");
        } else {

            [self.managedObjectContext.parentContext performBlock:^{
                internalError = nil;
                save = NO;

                [self.managedObjectContext.parentContext log]; // See log 1.2 below

                save = [self.managedObjectContext.parentContext save:&internalError];
                if (!save) {
                    NSLog(@"Error saving data to disk!");
                }
            }];

        }
    }];
    *error = [DKError errorWithNSError:internalError]; // Custom error class
    return save;
}

親 - 子コンテキスト コード

- (NSManagedObjectContext *)writerObjectContext
{
    if (_writerObjectContext != nil)
        return _writerObjectContext;

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _writerObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        [_writerObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _writerObjectContext;
}

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setParentContext:[self writerObjectContext]];

    return _managedObjectContext;
}

ログ 1.1

Inserted objects:
{(
    <Entity: 0x9595120> (entity: Entity; id: 0x9582d40 <x-coredata:///Entity/t24D0F98B-CB94-41D3-BEDD-79913454A9152> ; data: {
    [...]
    dateAttribute = "2013-07-12 10:36:31 +0000";
    stringAttribute = ricercaEntity;
    [...]
})
)}

ログ 1.2

Inserted objects:
{(
    <Entity: 0xb53ce80> (entity: Entity; id: 0x9582d40 <x-coredata:///Entity/t24D0F98B-CB94-41D3-BEDD-79913454A9152> ; data: {
    [...]
    dateAttribute = "2013-01-05 11:00:00 +0000";
    stringAttribute = nil;
    [...]
})
)}

アップデート

managedObjectコンテキストに追加されたものはコンテキストnilで初期化されることに言及する必要がありました。次に、呼び出す前saveContext:に の存在を確認しobject.managedObjectContext、それが nil の場合は[self managedObjectContext]、上記のメソッドで作成された として設定します。したがって、managedObjectが nil コンテキストで作成された場合、または次のように作成された場合:

+ (id)newObjectForInsertion
{
    return [[self alloc] initWithEntity:[self entityDescription] insertIntoManagedObjectContext:[DKDatabaseManager defaultManager].managedObjectContext];
}

関連する managedObjectContext は同じキュー (NSMainQueueConcurrencyType) にあります。

それ以外の場合、すべての同時実行チェーンmanagedObjectを使用して作成すると、YES が返され、すべての変更が親コンテキストに渡されます。+newObjectForInsertionsaveContext:

それがバグなのか、それとも CoreData の動作方法なのかはわかりません。

Apple Developer Forums の同じ問題:

https://devforums.apple.com/thread/174677?tstart=90

4

1 に答える 1