Je peux facilement obtenir l'ID d'un objet dans Core Data en utilisant le code suivant:
NSManagedObjectID *moID = [managedObject objectID];
Cependant, existe-t-il un moyen de sortir un objet du magasin de données de base en lui attribuant un ID d'objet spécifique? Je sais que je peux le faire en utilisant un NSFetchRequest, comme ceci:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(objectID = %@)", myObjectID];
[fetchRequest setPredicate:predicate];
Cependant, j'aimerais le faire d'une manière qui ne lance pas sa propre demande de récupération. Des idées?
Réponses:
Tu veux:
Récupère l'objet du magasin qui a cet ID, ou nul s'il n'existe pas.
(Attention: il existe deux méthodes sur NSManagedObjectContext avec des noms d'apparence similaire qui m'ont fait trébucher. Pour les aider à rester dans l'ordre, voici ce que font les deux autres:
... créera un objet fault avec l'ID d'objet fourni, qu'un tel objet existe ou non dans le magasin. S'il n'existe pas, tout ce qui déclenche l'erreur échouera sauf si vous insérez d'abord l'objet avec NSManagedObjectContext
insertObject:
. La seule utilisation que j'ai trouvée pour cela est de copier des objets d'un magasin à un autre tout en préservant les ObjectID.... renverra l'objet qui a cet ID, s'il a été extrait du magasin par ce managedObjectContext. Si quelqu'un sait à quoi cette méthode est utile, veuillez commenter.)
[eta.: Une autre différence importante entre la première méthode et les deux autres est qu'elle
existingObjectWithID:error:
ne renvoie jamais de faute; il récupère toujours l'objet entier pour vous. Si vous essayez d'éviter cela (par exemple, travailler avec un objet coûteux à récupérer avec une grande propriété blob), vous devez être intelligent avecobjectWithID:
ouobjectRegisteredForID:
, qui ne déclenche pas les défauts; ou utilisez une demande de récupération correctement configurée.]la source
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID
est probablement utile lorsque vous voulez juste voir si un objet existe déjà dans le contexte et que vous ne voulez pas le récupérer.-tableView:didSelectRowAtIndexPath:
UIAlertView avec oui / non s'affiche. Sur "oui" - il y a du travail avec l'objet. J'utiliseNSFetchedResultsController
+ les mises à jour CoreData de fond à distance. Je ne peux donc pas stocker d'objet: tant que l'alerte est à l'écran, le stockage peut être mis à jour et l'objet supprimé. Je stocke objectId, puis le récupère une fois de plus dans le délégué d'alerte. Parce que j'utiliseNSFetchedResultsController
- tous les objets nécessaires sont déjà dans leur contexte à ce moment. De plus, quand il n'y a pas d'objet dans le contexte, CoreData ne devrait pas rendre la récupération inutile.objectWithId:
- la nécessité d'appeler d'insertObject
abord pour éviter une augmentation d'exception lors d'une tentative de déclenchement d'une faute n'était en effet pas évidente pour moi.objectRegisteredForID:
est utile lorsque vous avez une liste des objectID d'une opération dans un autre contexte et que vous souhaitez uniquement mettre à jour ceux qui peuvent avoir des données périmées dans le contexte local. Cela permet de garder votre graphique d'objets (et donc l'utilisation de la mémoire) sous contrôle, et c'est mieux que de parcourir-registeredObjects
et de vérifier les objectID pour voir si un objet est défectueux pour votre contexte.objectWithID:
est la méthode que vous recherchez, et c'est la méthode recommandée pour ce faire.objectWithID:
utilisera efficacement NSManagedObjectContext pour extraire l'objet uniquement autant de niveaux que nécessaire - contrairement à certains des autres moyens de le faire.objectWithID:
utilisera correctement les informations en mémoire dans les contextes parents, le coordinateur de magasin persistant et le magasin persistant lui-même avant d'aller au stockage de sauvegarde.Cette question est traitée en détail dans la session 2012 de la WWDC «Meilleures pratiques en matière de données de base».
la source
Version Swift 5:
https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506686-existingobject
il existe également des méthodes
object(with:)
ouregisteredObject(for:)
. En fonction de ce dont vous avez besoin.la source