iOS de Base de Données lors de l'enregistrer dans le contexte?
Je vais avoir des plantages aléatoires avec base de données en raison de la simultanéité et le multithreading. Je sais que les données de base n'est pas thread-safe. J'ai aussi trouvé un couple d'autres réponses sur la façon de créer un ThreadedDataService et instancier contexte distinct pour chaque thread.
C'est un peu trop pour moi d'avaler en ce moment, donc j'essaie de trouver un moyen plus facile de sortir.
La solution que je suis en train en ce moment est simple: de l'enregistrement des données par le thread principal. Cependant, maintenant, une nouvelle question se pose: impasse. L'application ne répond plus, parce que chacun de mes insertions d'un nouveau NSManagedObject est suivi par un appel à enregistrer. (c'est ma meilleure supposition).
La lecture de l'App Délégué de la documentation, j'ai remarqué qu'il me conseille d'enregistrer contexte dans applicationWillTerminate.
Ma question est: est-ce à une longue opération qui permet d'insérer de nouveaux événements à chaque minute, et l'utilisateur n'est pas requis pour voir les mises à jour propagées à tous les contrôleurs immédiatement, quand est-il un bon moment pour moi pour sauver le contexte?
J'ai le sentiment que la sauvegarde de contexte pour chaque enregistrement est peut-être trop?
-(void)insertNewEvent
{
//Create a new instance of the entity managed by the fetched results controller.
NSManagedObjectContext *context = [self.fetchedResultsController.managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsControllerfetchRequest] entity];
Event*newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
//use accessor methods to set default values
//Save the context. > IS THIS REALLY NEEDED HERE?
NSError *error = nil;
if (![context save:&error])
{
}else
{
if(newManagedObject!=nil)
{
currentState= newManagedObject;
[currentRecord addEvent:newManagedObject];
//Is this call needed?
[self saveApplicationRecords];
}
}
}
J'ai méthodes comme celles qui sont définies pour l'ensemble de mes objets gérés, est-ce suffisant si je l'appelle, une telle méthode sur un thread principal tous les 10 à 15 minutes pour enregistrer les modifications en attente, plutôt que de le faire après chaque enregistrement d'insertion?
-(void)saveApplicationRecords
{
NSLog(@"saveApplicationRecords");
NSManagedObjectContext *context = [self.applicationRecordsController.managedObjectContext];
//Save the context.
NSError *error = nil;
if (![context save:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
Une question supplémentaire après la lecture de macbirdie réponse: est ce genre de méthode juridique en base de données?
-(Event*)insertAndReturnNewEventWithDate:(NSDate*)date_ type:(int)type
{
NSManagedObjectContext *context = [self.dreamEventsController managedObjectContext];
NSEntityDescription *entity = [[self.dreamEventsController fetchRequest] entity];
DreamEvent *newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
//handle properties
NSError *error = nil;
if (![context save:&error])
{
return nil;
}else
{
return newManagedObject ;
}
}
Merci!
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas à enregistrer le contexte qui est le début du processus, en particulier lorsque vous souhaitez modifier l'objet par la suite.
Dans la plupart des cas, vous devez créer un
NSManagedObjectContext
pour que les modifications que vous vous apprêtez à effectuer sur la base de données. Afin de créer des objets, de remplir les propriétés requises, alors envoyezsave
et de réaliser l'ensemble dumergeChangesFromContextDidSaveNotification:
truc avec le contexte principal (le plus souvent en cours d'exécution sur le thread principal, afin de l'utiliserperformSelectorOnMainThread
... message).Par défaut d'un objet créé et retourné par
NSManagedObjectContext
est autoreleased. Si vous avez créé un objet et que vous souhaitez modifier dans un formulaire par exemple, vous pouvez appelersetRetainsRegisteredObjects:
OUI pour la gestion du contexte de l'objet avant la création de l'objet, de sorte qu'il tient à l'objet créé jusqu'à ce que vous avez terminé avec elle. Rappelez-vous qu'il est recommandé de ne pas gérer laNSManagedObject
s' cycle de vie sur votre propre, vous devez laisser leNSManagedObjectContext
le faire. Donc, avec cela à l'esprit, vous n'avez pas à conserver leNSManagedObject
. Après l'opération d'enregistrement, c'est non par le contexte et supprimé de la mémoire. Rien n'est requise de votre part.Réponse à la mise à jour de la question de la partie
Il serait probablement mieux si vous avez renvoyé une
NSManagedObjectID
(à l'aide de[object objectID]
) au lieu de l'objet lui-même. Il permet de disposer de l'objet par le contexte, et si l'un a besoin de l'objet pour le modifier ou la récupération de données (par exemple à partir d'autres contextes), ils peuvent chercher à partir de la boutique séparément.Même si vous n'enregistrez pas le contexte, l'objet nouvellement créé est là et ensuite vous pouvez décider si vous voulez garder ou non l'objet.
Après l'enregistrement sur l'autre main, si le contexte existe encore, il peut renvoyer l'objet donné, avec
NSManagedObjectID
à vous à partir de la mémoire cache, sans toucher à la base de données.Sur une autre main ;), dans votre cas, vous pouvez très bien le retour en toute sécurité l'objet, depuis le
NSManagedObjectContext
de la création, il existe encore, de sorte que l'objet existe toujours ainsi, bien que déjà dans l'autorelease pool.