1

Dans mon application Données de base, j'initialise les objets gérés en utilisant initWithEntity:insertIntoManagedObjectContext: avec un contexte nil. J'utilise ensuite [managedObjectContext insertObject:object] pour insérer l'objet dans le contexte, si/quand nécessaire.Les propriétés de l'objet Données de base sont nulles lorsque l'objet géré est initialisé SANS insertion dans un contexte d'objet géré

Il semble que c'est la raison pour laquelle l'API insertObject: existe. Pour insérer un objet géré qui n'a pas été inséré lors de la création. Mais lorsque la logique ci-dessus est utilisée, les objets (lorsqu'ils sont récupérés ultérieurement dans le MOC) ont des propriétés nulles. Les chaînes sur l'objet ne sont pas conservées.

Si je place initWithEntity:insertIntoManagedObjectContext: avec unnon nulle MOC, les propriétés sont persistaient et tout fonctionne correctement. Dans ce cas, je n'appelle pas insertObject:.

Les deux variances du code sont ci-dessous. Il suffit de basculer le drapeau useNilContext pour essayer chacun.

// ... 

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; 
} 

Plus tard, quand je vais chercher l'objet de base de données et inspectez, je reçois un comportement différent selon si l'objet a été initialement inséré dans un MOC. Si le MOC était nil, toutes les propriétés de l'objet sont nil après l'extraction.

En utilisant initWithEntity:insertIntoManagedObjectContext: avec un nil MOC:

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

Initialiser avec un MOC non nul:

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

Comme vous pouvez le voir, les propriétés sont nil après la récupération lorsque l'objet n'a pas été initialement inséré dans un MOC. Quand il est initialement inséré dans le MOC, les propriétés sont non-nulles et persistantes.

Pourquoi ces propriétés ne sont-elles pas persistantes? Je pense que les deux stratégies de code devraient être identiques.

Existe-t-il une autre étape qui doit être prise pour conserver les propriétés d'un objet géré qui a initialement un nil Managed Object Context?

+0

Avez-vous essayé d'inspecter l'objet stringProperty juste avant et juste après l'avoir défini. Est-ce que ça se passe dans les deux cas? – Yan

Répondre

1

Non, il n'y a pas d'étape supplémentaire. En ce qui concerne les raisons pour lesquelles les propriétés ne sont pas sauvegardées, il se passe quelque chose d'autre dans votre code qui cause le problème. L'attribution d'un nouvel objet géré fonctionne de la même manière, que vous fournissiez un contexte ou que vous utilisiez un contexte nul, puis que vous insériez l'objet.

Il semble que vous soyez en train de mélanger des contextes, mais il est difficile d'en être certain. Lorsque vous appelez insert:, vous utilisez [TDBackend sharedBackend].managedObjectContextPrivateQueue. Mais lorsque vous enregistrez les modifications, vous utilisez self.managedObjectContextPrivateQueue. Pendant ce temps, lorsque useNilContext est NO, vous créez l'objet géré en utilisant [XYZBackend sharedBackend].managedObjectContextPrivateQueue. Et vous synchronisez les choses avec un appel de bloc sur [ZYZBackend sharedBackend].managedObjectContextPrivateQueue. C'est quatre contextes différents dans ce qui devrait être un morceau de code assez simple. Il est impossible d'être certain mais cela donne l'impression distincte que vous utilisez le mauvais contexte à un certain moment

+0

merci, ce sont des fautes de frappe dans le pseudo-code I ci-dessus conçu pour cette question. Corrigée.Doit seulement utiliser le single [[XYZBackend sharedBackend] .managedObjectContextPrivateQueue') Ma vraie version de ceci utilise un seul contexte privé (et un contexte principal). – pkamb