1

私のコアデータアプリケーションではinitWithEntity:insertIntoManagedObjectContext:nilコンテキストで初期化しています。その後、必要に応じて、[managedObjectContext insertObject:object]を使用して、オブジェクトをコンテキストに挿入します。管理対象オブジェクトが初期化され、管理オブジェクトコンテキストに挿入されていない場合、コアデータオブジェクトのプロパティはnilです

これがinsertObject: APIが存在する理由です。作成中に挿入されなかった管理対象オブジェクトを挿入する。

しかし、上記のロジックを使用すると、オブジェクト(後でMOCからフェッチされるとき)にはnilプロパティがあります。オブジェクト上の文字列は永続化されません。

私が代わりにnil以外 MOCとinitWithEntity:insertIntoManagedObjectContext:を使用する場合は、プロパティ永続化されると、すべてが正常に動作します。この場合、私はinsertObject:に電話をしません。

コードの2つの違いは以下のとおりです。 useNilContextフラグをトグルするだけで、それぞれ試してみることができます。私はコアデータからオブジェクトをフェッチし、それを点検するとき

// ... 

BOOL useNilContext = YES; 

[[XYZBackend sharedBackend].managedObjectContextPrivateQueue performBlock:^{ 
    XYZObject *object = [XYZObject objectFromJSON:json useNilContext:useNilContext]; 

    if (useNilContext) { 
     [[XYZBackend sharedBackend].managedObjectContextPrivateQueue insertObject:object]; 
    } 

    NSError *privateQueueError = nil; 
    if (![[XYZBackend sharedBackend].managedObjectContextPrivateQueue save:&privateQueueError]) { 
     NSLog(@"Error saving Core Data managed object context in private queue! %@", privateQueueError); 
    } 
}]; 

// ... 


+ (instancetype)managedObjectFromJSON:(NSDictionary *)json useNilContext:(BOOL)useNilContext { 
    __block XYZManagedObject *object = nil; 

    [[XYZBackend sharedBackend].managedObjectContextPrivateQueue performBlockAndWait:^{ 
     NSEntityDescription *entity = [NSEntityDescription entityForName:NSStringFromClass([self class]) inManagedObjectContext:[XYZBackend sharedBackend].managedObjectContextPrivateQueue]; 

     NSManagedObjectContext *context = [XYZBackend sharedBackend].managedObjectContextPrivateQueue; 
     if (useNilContext) { 
      context = nil; 
     } 

     object = [[XYZManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; 

     object.stringProperty = json[@"string"]; 
    }]; 

    return object; 
} 

その後、私は、オブジェクトが最初にMOCに挿入された場合に応じて異なる動作を取得します。 MOCがnilの場合、オブジェクトのプロパティはすべて、フェッチ後にnilになります。 nil以外のMOCで初期化

Printing description of object: 
<XYZObject: 0x60b0000b80d0> (entity: XYZObject; id: 0xd000000000040000 <x-coredata://5F843602-C03B-4339-AC50-0F70FD1545C9/XYZObject/p1> ; data: { 
    stringProperty = nil; 
}) 

Printing description of object: 
<XYZObject: 0x60b000054680> (entity: XYZObject; id: 0xd000000000040000 <x-coredata://72502855-7204-4485-828C-BC07C51F7FE2/XYZObject/p1> ; data: { 
    stringProperty = "string"; 
}) 

あなたが見ることができるようにオブジェクトがありませんでしたときにフェッチした後に、プロパティがnilあるnil MOCとinitWithEntity:insertIntoManagedObjectContext:を使用して

最初にMOCに挿入される。それが最初にMOCに挿入されるとき、プロパティは非ゼロであり、持続される。

なぜこれらのプロパティは保持されませんか?私は2つのコード戦略が同一でなければならないと思います。

最初にnil管理オブジェクトコンテキストを持つ管理対象オブジェクトのプロパティを維持するためには、別の手順が必要ですか?

+0

設定した前後でオブジェクトstringPropertyを検査しようとしましたか?どちらの場合でも実際に設定されていますか? – Yan

答えて

1

いいえ、余分な手順はありません。なぜプロパティが保存されないのかについては、問題の原因となっているコードに何か他のことがあります。新しい管理対象オブジェクトを割り当てることは、コンテキストを提供するかどうか、またはnilコンテキストを使用するかどうかに関わらず、オブジェクトを挿入するかどうかにかかわらず同じです。

コンテキストを混在させているようですが、確信が持てません。 insert:に電話するときは、[TDBackend sharedBackend].managedObjectContextPrivateQueueを使用します。しかし、変更を保存するときはself.managedObjectContextPrivateQueueを使用します。一方、useNilContextNOの場合、[XYZBackend sharedBackend].managedObjectContextPrivateQueueを使用して管理オブジェクトを作成します。そして、あなたは[ZYZBackend sharedBackend].managedObjectContextPrivateQueueのブロックコールと物事を同期させています。それは、かなり単純なコードでなければならないものに、4つの異なるコンテキストがあります。それは特定することは不可能ですが、あなたが間違ったコンテキストを使用しているという印象があります。

+0

ありがとう、これらは私がこの質問のために作り上げた上記の擬似コードのタイプミスです。修正されました。ただ1つの '[XYZBackend sharedBackend] .managedObjectContextPrivateQueue'を使うべきです。これの私の実際のバージョンは、単一のプライベートコンテキスト(およびメインコンテキスト)を使用しています。 – pkamb

関連する問題