É possível obter facilmente o ID de um objeto no Core Data usando o seguinte código:
NSManagedObjectID *moID = [managedObject objectID];
No entanto, existe uma maneira de obter um objeto do armazenamento de dados principal, fornecendo a ele um ID de objeto específico? Eu sei que posso fazer isso usando um NSFetchRequest, como este:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(objectID = %@)", myObjectID];
[fetchRequest setPredicate:predicate];
No entanto, gostaria de fazê-lo de uma maneira que não inicie sua própria solicitação de busca. Alguma ideia?
Respostas:
Você quer:
Busca o objeto da loja que possui esse ID ou nulo, se ele não existir.
(Lembre-se: existem dois métodos no NSManagedObjectContext com nomes semelhantes que me deram uma surra. Para ajudar a mantê-los em ordem, veja o que os outros dois fazem:
... criará um objeto de falha com o ID do objeto fornecido, se esse objeto realmente existe ou não no armazenamento. Se não existir, tudo o que acionar a falha falhará, a menos que você insira o objeto primeiro com o NSManagedObjectContext
insertObject:
. O único uso que encontrei para isso é copiar objetos de uma loja para outra, preservando os ObjectIDs.... retornará o objeto que possui esse ID, se ele foi buscado na loja por este managedObjectContext. Se alguém souber para que serve esse método, comente.)
[eta .: Outra diferença importante entre o primeiro método e os outros dois é que
existingObjectWithID:error:
nunca retorna uma falha; ele sempre busca o objeto inteiro para você. Se você está tentando evitar isso (por exemplo, trabalhando com um objeto caro para buscar com uma grande propriedade de blob), precisa ser inteligente comobjectWithID:
ouobjectRegisteredForID:
, o que não gera falhas; ou use uma solicitação de busca configurada corretamente.]fonte
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID
provavelmente é útil quando você deseja apenas ver se um objeto já existe no contexto e não deseja buscá-lo.-tableView:didSelectRowAtIndexPath:
UIAlertView com yes / no é exibido. Em "sim" - há algum trabalho com objeto. Eu usoNSFetchedResultsController
+ atualizações em segundo plano CoreData do controle remoto. Portanto, não consigo armazenar objetos: enquanto o alerta estiver na tela, o armazenamento pode ser atualizado e o objeto removido. Eu guardo objectId e, em seguida, recupero-o novamente no delegado de alerta. Porque eu usoNSFetchedResultsController
- todos os objetos necessários já estão em contexto neste momento. Além disso, quando não há objeto no contexto, o CoreData não deve fazer tentativas de busca inúteis.objectWithId:
- a necessidade de ligarinsertObject
primeiro para evitar um aumento de exceção na tentativa de disparar uma falha era realmente óbvia para mim.objectRegisteredForID:
é útil quando você possui uma lista de objectIDs de uma operação em outro contexto e deseja atualizar apenas aqueles que podem ter dados obsoletos no contexto local. Isso mantém seu gráfico de objetos (e, portanto, o uso de memória) sob controle, e é melhor do que percorrer-registeredObjects
e verificar os IDs dos objetos para ver se um objeto está com falha no seu contexto.objectWithID:
é o método que você está procurando e é a maneira recomendada de fazer isso.objectWithID:
usará eficientemente o NSManagedObjectContext para extrair o objeto apenas quantos níveis forem necessários - ao contrário de outros meios para fazer isso.objectWithID:
usará corretamente as informações da memória nos contextos pai, o coordenador de armazenamento persistente e o próprio armazenamento persistente antes de ir para o armazenamento de backup.Isso é abordado em profundidade na sessão da WWDC 2012 "Melhores práticas de dados principais".
fonte
Versão Swift 5:
https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506686-existingobject
também existem métodos
object(with:)
ouregisteredObject(for:)
. Dependendo do que você precisa.fonte