Belirli Nesne Kimliğinden Temel Veri nesnesi nasıl alınır?


120

Aşağıdaki kodu kullanarak Core Data'da bir nesnenin kimliğini kolayca alabilirim:

NSManagedObjectID *moID = [managedObject objectID];

Bununla birlikte, bir nesneyi belirli bir nesne kimliği vererek çekirdek veri deposundan çıkarmanın bir yolu var mı? Bunu bir NSFetchRequest kullanarak yapabileceğimi biliyorum, şöyle:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(objectID = %@)", myObjectID];
[fetchRequest setPredicate:predicate];

Ancak, bunu kendi getirme isteğini başlatmayacak şekilde yapmak istiyorum. Herhangi bir fikir?


Ancak getirme isteği yöntemiyle, önceden getirilecek özellikleri veya ilişkileri ayarlayabilirsiniz; bu, bir şeylere erişirken çok daha fazla sorgu yerine size mükemmel verimlilik sağlar.
malhal

Yanıtlar:


208

İstediğiniz:

-(NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID
                                   error:(NSError **)error

Bu kimliğe sahip depodan nesneyi veya yoksa nil'i getirir.

(Dikkat edin: NSManagedObjectContext'te benzer görünen adlara sahip iki yöntem vardır ve beni heyecanlandırır. Onları düz tutmaya yardımcı olmak için, işte diğer ikisinin yaptığı:

-(NSManagedObject *)objectWithID:(NSManagedObjectID *)objectID

... böyle bir nesne depoda gerçekten mevcut olsun veya olmasın , sağlanan nesne kimliği ile bir hata nesnesi yaratacaktır . Mevcut değilse, nesneyi önce NSManagedObjectContext ile eklemediğiniz sürece, hatayı tetikleyen herhangi bir şey başarısız olacaktır insertObject:. Bunun için bulduğum tek kullanım, ObjectID'leri korurken nesneleri mağazadan depolamaya kopyalamak.

-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID

..., bu kimliği olduğu nesneyi dönecektir eğer bu managedObjectContext tarafından deposundan alınamadı. Bu yöntemin ne işe yaradığını bilen biri varsa, lütfen yorum yapın.)

[eta .: İlk yöntemle diğer ikisi arasındaki bir diğer önemli fark ise existingObjectWithID:error:hiçbir zaman hata vermemesidir; her zaman sizin için tüm nesneyi getirir. Bundan kaçınmaya çalışıyorsanız (örneğin, büyük bir blob özelliğine sahip getirilmesi pahalı bir nesneyle çalışmak), objectWithID:veya objectRegisteredForID:hataları tetiklemeyen veya konusunda akıllı olmalısınız ; veya uygun şekilde yapılandırılmış bir getirme isteği kullanın.]


11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDMuhtemelen, bir nesnenin bağlam içinde zaten var olup olmadığını görmek istediğinizde ve onu getirmek istemediğinizde yararlıdır.
Tony

Durumum. On -tableView:didSelectRowAtIndexPath: UIAlertView evet ile / hayır görüntülenir. "Evet" üzerine - nesneyle ilgili bazı çalışmalar var. NSFetchedResultsControllerUzaktan + arka plan CoreData güncellemelerini kullanıyorum . Bu yüzden nesneyi saklayamıyorum: uyarı ekranda iken, depolama güncellenebilir ve nesne kaldırılabilir. Nesne kimliğini depoladım, ardından uyarı temsilcisine bir kez daha geri getirdim. Çünkü kullandığım için NSFetchedResultsController- gerekli tüm nesneler şu anda zaten bağlam içindedir. Dahası, bağlamda nesne olmadığında, CoreData gereksiz getirme girişimlerinde bulunmamalıdır.
kpower

güzel cevap, teşekkür ederim! bu yöntem isimleri gerçekten aldatıcıdır. yanlış olanla her şeyi alt üst etmek çok kolay
çakal

Harika cevap, açıklığa kavuşturduğunuz için teşekkürler objectWithId:- insertObjectbir hatayı ateşleme teşebbüsünde bir istisna artışını önlemek için önce arama ihtiyacı bana gerçekten açık değildi.
Stanislav Pankevich

3
objectRegisteredForID:başka bir bağlamdaki bir işlemden nesne kimlikleri listeniz olduğunda ve yalnızca yerel bağlamda eski verilere sahip olabilecekleri güncellemek istediğinizde kullanışlıdır. Bu, nesne grafiğinizi (ve dolayısıyla bellek kullanımını) kontrol altında tutar ve -registeredObjectsbağlamınız için bir nesnenin hatalı olup olmadığını görmek için nesne kimliklerini kontrol etmekten daha iyidir .
Sterling Archer

4

objectWithID:aradığınız yöntemdir ve bunu yapmanın önerilen yolu budur. objectWithID:NSManagedObjectContext'i, bunu yapmanın diğer yollarından farklı olarak, nesneyi yalnızca gerektiği kadar seviyeye çekmek için verimli bir şekilde kullanır. objectWithID:arka depolamaya gitmeden önce bellek içi bilgileri ana bağlamlarda, kalıcı depo koordinatöründe ve kalıcı deponun kendisini doğru bir şekilde kullanacaktır.

Bu, WWDC 2012 oturumu "Temel Veri En İyi Uygulamaları" nda derinlemesine ele alınmıştır .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.