86 votes

Comment traiter les instances temporaires NSManagedObject?

J'ai besoin de créer NSManagedObject cas, faire des trucs avec eux et puis poubelle ou de les stocker à sqlite db. Le problème est que je ne peut pas créer des instances de NSManagedObject étrangers à MSManagedObjectContext et cela signifie que je dois éclaircir quelque peu après je décide que je n'ai pas besoin de certains objets dans ma db.

De traiter avec elle, j'ai créé une banque de mémoire à l'aide de la même coordonnateur et je suis plaçant temporairement des objets en utilisant assignObject:toPersistentStore. Maintenant, comment puis-je m'assurer que ces objets temporaires ne pas obtenir les données, dont j'extrais de la commune pour les deux magasins contexte? Ou dois-je créer des contextes différents pour une telle tâche?


UPD:

Maintenant, je vais penser à faire autre contexte pour la mémoire vive. Comment puis-je déplacer des objets à partir d'un contexte à l'autre? Juste à l'aide de [contexte insertObject:]? Il travaillera sur OK dans cette configuration? Si j'insère un objet à partir du graphe d'objets, le graphique permet aussi de s'insérés dans leur contexte?

147voto

Marcus S. Zarra Points 32178

Pour ce faire, le moyen le plus simple consiste à créer vos instances NSManagedObject sans un NSManagedObjectContext associé.

 NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:myMOC];
NSManagedObject *unassociatedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
 

Puis quand vous voulez le sauvegarder:

 [myMOC insertObject:unassociatedObject];
NSError *error = nil;
if (![myMoc save:&error]) {
  //Respond to the error
}
 

40voto

railwayparade Points 3448

iOS5 offre une solution plus simple Mike Weller réponse. Au lieu d'utiliser un enfant NSManagedObjectContext. Il supprime la nécessité de trampoline par NSNotificationCenter

Pour créer un enfant de contexte:

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
childContext.parentContext = myMangedObjectContext;

Ensuite créer vos objets à l'aide de l'enfant contexte:

NSManagedObject *o = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject" inManagedObjectContext:childContext];

Les modifications ne sont appliquées que lorsque l'enfant contexte est enregistré. Donc, pour enregistrer les modifications, il suffit de ne pas enregistrer.

Il y a toujours une limitation sur les relations. c'est à dire Vous ne pouvez pas créer des relations aux objets dans d'autres contextes. Pour contourner cette utilisation objectID, pour obtenir l'objet de l'enfant contexte. par exemple.

NSManagedObjectID *mid = [myManagedObject objectID];
MyManagedObject *mySafeManagedObject = [childContext objectWithID:mid];
object.relationship=mySafeManagedObject;

Remarque, l'économie de l'enfant contexte applique les modifications pour le contexte parent. En enregistrant le contexte parent persiste les modifications.

Voir la wwdc 2012 session 214 pour une explication complète.

9voto

Mike Weller Points 28387

La bonne façon d'atteindre ce genre de chose est un objet géré contexte. Vous créez un objet géré avec la même persistance:

NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
[tempContext setPersistentStore:[originalContext persistentStore]];

Ensuite, vous ajoutez de nouveaux objets, de muter, etc.

Quand vient le temps de l'enregistrer, vous avez besoin de les appeler [tempContext enregistrer:...] sur le tempContext, et la poignée de la notification d'enregistrement de fusionner dans votre contexte d'origine. À jeter les objets, il suffit de relâcher ce contexte temporaire et de l'oublier.

Ainsi, lorsque vous enregistrez le contexte temporaire, les modifications sont conservées dans le magasin et vous avez juste besoin d'obtenir ces modifications dans votre contexte principal:

/* Called when the temp context is saved */
- (void)tempContextSaved:(NSNotification *)notification {
    /* Merge the changes into the original managed object context */
    [originalContext mergeChangesFromContextDidSaveNotification:notification];
}

// Here's where we do the save itself

// Add the notification handler
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(tempContextSaved:)
                                             name:NSManagedObjectContextDidSaveNotification
                                           object:tempContext];

// Save
[tempContext save:NULL];
// Remove the handler again
[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:NSManagedObjectContextDidSaveNotification
                                              object:tempContext];

C'est aussi la façon dont vous devez gérer le multi-thread de base de données. Un contexte par thread.

Si vous avez besoin d'accéder à des objets existants à partir de ce contexte temporaire (pour ajouter des relations, etc.) ensuite, vous devez utiliser l'IDENTIFIANT d'objet pour obtenir une nouvelle instance comme ceci:

NSManagedObject *objectInOriginalContext = ...;
NSManagedObject *objectInTemporaryContext = [tempContext objectWithID:[objectInOriginalContext objectID]];

Si vous essayez d'utiliser un NSManagedObject dans le mauvais contexte, vous obtiendrez des exceptions lors de l'enregistrement.

9voto

user134611 Points 367

La création d'objets temporaires à partir d'un contexte nil fonctionne correctement jusqu'à ce que vous essayiez réellement d'avoir une relation avec un objet dont le contexte! = Nil!

assurez-vous que ça vous va.

8voto

quellish Points 5475

Ce que vous décrivez est exactement ce qu'un NSManagedObjectContext.

À Partir De Données De Base Guide De Programmation: Les Bases De Données

Vous pouvez penser à un objet géré contexte comme un être intelligent scratch pad. Lorsque vous aller chercher des objets dans un magasin persistant, vous apportez des copies temporaires sur le bloc-notes où ils forment un objet graphique (ou une collection de graphes d'objets). Vous pouvez ensuite modifier ces objets comme vous le souhaitez. Sauf si vous avez réellement enregistrer ces modifications, cependant, la persistance de magasin reste inchangée.

Et De Base De Données Guide De Programmation: Objet Géré De Validation

C'est également à la base l'idée de la gestion du contexte de l'objet représentant un "bloc-notes"-en général, vous pouvez apporter des objets gérés sur le bloc-notes et de les modifier comme vous le souhaitez avant de finalement soit de commettre les changements ou les jeter.

NSManagedObjectContexts sont conçus pour être léger. Vous pouvez créer et jetez-les à volonté - c'est la persistance de magasins de coordinateur et de dépendances qui sont "lourds". Un seul magasin persistant coordonnateur peut avoir de nombreux contextes associés. En vertu de l'ancien fil de confinement modèle, cela signifierait fixer le même magasin persistant coordonnateur de chaque contexte. Aujourd'hui, il signifierait la connexion imbriqués les contextes d'une racine de contexte associé à la persistance de coordonnateur du magasin.

Créer un contexte, de créer et de modifier des objets gérés dans ce contexte. Si vous souhaitez les conserver et de communiquer ces modifications, enregistrez le contexte. Sinon l'éliminer.

La tentative de créer des objets gérés indépendamment d'un NSManagedObjectContext est d'avoir des ennuis. Rappelez-vous que la Base de Données est en fin de compte un changement de mécanisme de suivi pour un objet graphique. De ce fait, les objets gérés sont vraiment une partie de la gestion du contexte de l'objet. Le contexte observe de leur cycle de vie, et sans le contexte pas tous de l'objet géré fonctionnalité fonctionne correctement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X