1

プライベート コンテキストをメイン コンテキストにマージする必要があるマルチスレッド アプリケーションがあり、メイン コンテキストは永続ストレージ コントローラーに接続されています。

また、管理されていない一時オブジェクトを作成する必要もあります (後で管理することを決定するまで)。

まず、次のように一時オブジェクトを作成しようとしました。

NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:myMainQueueContext];
User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

オブジェクトを保持するかどうかを決定した後、私は単純に;

[privateContext insertObject:user];

アプリケーションをマルチスレッド化する前はうまく機能していましたが、少し分解して子/親コンテキストによるマルチスレッド同時実行を追加したところ、期待どおりの結果が得られませんでした。

コンテキストの「registeredObjects」を見ると、作成されて挿入されたユーザーが privateContext で管理されていることがわかります。保存後、それに応じて mainContext が変更され、hasChanges があり、registeredObjects に 1 つのオブジェクトがあることがわかります。

しかし、mainContext のその registeredObject をよく見ると、空になっていることがわかります。内容なし。タイプに応じて、すべての属性は nil または 0 です。したがって、これは objectId が同じではないためである可能性があると予想されます...しかし、それは ;( 同じオブジェクトですが、内容はありません。

ここの別の投稿で、この懸念について意見を得ようとしましたが、成功しませんでした。

親/メイン コンテキストにマージした後、子コンテキスト オブジェクトが空になる

とにかく、オブジェクトの作成方法を変更することで、ようやく機能するようになりました。

User* user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:privateContext];

突然、子オブジェクトが内容を失うことなく mainContext にマージされました。理由は不明ですが、残念ながら、これにより、一時的な管理されていないオブジェクトを作成できなくなりました... ;( Marcus Zarra が私を支持したことを読みました管理されていないオブジェクトの作成に関しては最初のアプローチですが、それは私のマルチスレッドアプリでのコンテキストのマージでは機能しません...

考えやアイデアを楽しみにしています-非同期ワーカースレッドで一時オブジェクトを作成しようとしているのは私だけですか?

編集

何が機能しているか、さらに重要なことに何が機能していないかを示す具体的なコード。

//Creatre private context and lnk to main context..
NSManagedObjectContext* privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

//Link private context to main context...
privateManagedObjectContext.parentContext = self.modelManager.mainManagedObjectContext;

[privateManagedObjectContext performBlock:^()
{
    //Create user
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.modelManager.mainManagedObjectContext];
    User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

    [user setGuid:@"123123"];
    [user setFirstName:@"Markus"];
    [user setLastName:@"Millfjord"];

    [privateManagedObjectContext insertObject:user];

    //Debug before we start to merge...
    NSLog(@"Before private save; private context has changes: %d", [privateManagedObjectContext hasChanges]);
    NSLog(@"Before private save; main context has changes: %d", [self.modelManager.mainManagedObjectContext hasChanges]);
    for (NSManagedObject* object in [privateManagedObjectContext registeredObjects])
        NSLog(@"Registered private context object; %@", object);

    //Save private context!
    NSError* error = nil;
    if (![privateManagedObjectContext save:&error])
    {
         //Oppps
         abort();
    }

    NSLog(@"After private save; private context has changes: %d", [privateManagedObjectContext hasChanges]);
    NSLog(@"After private save; main context has changes: %d", [self.modelManager.mainManagedObjectContext hasChanges]);

    for (NSManagedObject* object in [privateManagedObjectContext registeredObjects])
        NSLog(@"Registered private context object; %@", object);
    for (NSManagedObject* object in [self.modelManager.mainManagedObjectContext registeredObjects])
        NSLog(@"Registered main context object; %@", object);

     //Save main context!
     [self.modelManager.mainManagedObjectContext performBlock:^()
     {
         //Save main context!
         NSError* mainError = nil;
         if (![self.modelManager.mainManagedObjectContext save:&mainError])
         {
              //Opps again
              NSLog(@"WARN; Failed saving main context changes: %@", mainError.description);
              abort();
         }
    }];
}];

上記は、一時オブジェクトを作成してからコンテキストに挿入するため、機能しません。ただし、このわずかな mod は機能しますが、一時的なオブジェクトを持つことはできません...;

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.modelManager.mainManagedObjectContext];
    User* user = (User *)[[User alloc] initWithEntity:entity insertIntoManagedObjectContext:privateManagedObjectContext];

したがって、私は疑問に思っています。違いは何ですか?明らかに何か違いがあるはずですが、私にはわかりません。

4

1 に答える 1