จะรับวัตถุ Core Data จาก Object ID เฉพาะได้อย่างไร


120

ฉันสามารถรับ ID ของวัตถุใน Core Data ได้อย่างง่ายดายโดยใช้รหัสต่อไปนี้:

NSManagedObjectID *moID = [managedObject objectID];

อย่างไรก็ตามมีวิธีนำออบเจ็กต์ออกจากที่เก็บข้อมูลหลักโดยการให้ ID อ็อบเจ็กต์เฉพาะหรือไม่ ฉันรู้ว่าฉันสามารถทำได้โดยใช้ NSFetchRequest เช่นนี้:

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

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

อย่างไรก็ตามฉันต้องการดำเนินการในลักษณะที่ไม่ได้เริ่มต้นคำขอดึงข้อมูลของตัวเอง ความคิดใด ๆ ?


แต่ด้วยวิธีการร้องขอการดึงข้อมูลคุณสามารถตั้งค่าคุณสมบัติหรือความสัมพันธ์ที่จะดึงข้อมูลล่วงหน้าซึ่งจะให้ประสิทธิภาพที่ยอดเยี่ยมมากกว่าการสืบค้นอื่น ๆ อีกมากมายเมื่อคุณเข้าถึงสิ่งต่างๆ
malhal

คำตอบ:


209

คุณต้องการ:

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

ดึงอ็อบเจ็กต์จากสโตร์ที่มี ID นั้นหรือไม่มีหากไม่มีอยู่

(โปรดทราบ: มีสองวิธีใน NSManagedObjectContext ที่มีชื่อที่ดูเหมือนกันซึ่งทำให้ฉันสะดุดเพื่อช่วยให้ตรงต่อไปนี้เป็นสิ่งที่อีกสองอย่างทำ:

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

... จะสร้างวัตถุความผิดพลาดด้วย objectID ที่จัดเตรียมไว้ไม่ว่าวัตถุดังกล่าวจะมีอยู่จริงในร้านค้าหรือไม่ก็ตาม ถ้ามันไม่ได้อยู่ที่สิ่งที่เกิดเพลิงไหม้ความผิดจะล้มเหลวจนกว่าคุณจะแทรกวัตถุครั้งแรกกับ insertObject:NSManagedObjectContext สิ่งเดียวที่ฉันพบคือการคัดลอกวัตถุจากร้านค้าไปยังที่จัดเก็บในขณะที่รักษา ObjectIDs

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

... จะส่งคืนอ็อบเจ็กต์ที่มี ID นั้นหากมีการดึงข้อมูลจากสโตร์โดย ManagedObjectContext นี้ หากใครทราบว่าวิธีนี้มีประโยชน์อย่างไรกรุณาแสดงความคิดเห็น)

[eta.: ข้อแตกต่างที่สำคัญอีกประการระหว่างวิธีแรกกับอีกสองวิธีคือexistingObjectWithID:error:ไม่เคยส่งคืนความผิดพลาด มันจะดึงวัตถุทั้งหมดมาให้คุณเสมอ หากคุณกำลังพยายามหลีกเลี่ยงสิ่งนั้น (เช่นการทำงานกับวัตถุราคาแพงในการดึงข้อมูลที่มีคุณสมบัติหยดน้ำขนาดใหญ่) คุณจะต้องฉลาดด้วยobjectWithID:หรือobjectRegisteredForID:ซึ่งจะไม่ทำให้เกิดความผิดพลาด หรือใช้คำขอการดึงข้อมูลที่กำหนดค่าไว้อย่างเหมาะสม]


11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDอาจมีประโยชน์เมื่อคุณต้องการดูว่ามีวัตถุอยู่แล้วในบริบทหรือไม่และไม่ต้องการดึงข้อมูล
Tony

สถานการณ์ของฉัน บน-tableView:didSelectRowAtIndexPath: UIAlertView ที่มีใช่ / ไม่ใช่จะปรากฏขึ้น เมื่อ "ใช่" - มีการทำงานบางอย่างกับวัตถุ ฉันใช้NSFetchedResultsController+ อัพเดต CoreData พื้นหลังจากระยะไกล ดังนั้นฉันจึงไม่สามารถจัดเก็บวัตถุได้: ในขณะที่การแจ้งเตือนอยู่บนหน้าจอสามารถอัปเดตที่เก็บข้อมูลและนำวัตถุออกได้ ฉันจัดเก็บ objectId แล้วดึงข้อมูลอีกครั้งใน alert delegate เพราะฉันใช้NSFetchedResultsController- วัตถุที่จำเป็นทั้งหมดอยู่ในบริบทในขณะนี้ ยิ่งไปกว่านั้นเมื่อไม่มีวัตถุในบริบท CoreData ไม่ควรทำให้การดึงข้อมูลที่ไร้ประโยชน์
kpower

คำตอบที่ดีขอบคุณ! ชื่อวิธีการเหล่านี้ยุ่งยากมาก มันง่ายที่จะทำให้ทุกอย่างยุ่งเหยิงกับสิ่งที่ผิด
ลิ่วล้อ

คำตอบที่ยอดเยี่ยมขอบคุณสำหรับความกระจ่างเกี่ยวกับobjectWithId:- ความจำเป็นในการโทรinsertObjectก่อนเพื่อป้องกันการเพิ่มข้อยกเว้นในการพยายามยิงข้อผิดพลาดนั้นเป็นสิ่งที่ฉันไม่อาจเปิดเผยได้
Stanislav Pankevich

3
objectRegisteredForID:มีประโยชน์เมื่อคุณมีรายการ objectID จากการดำเนินการในบริบทอื่นและคุณต้องการอัปเดตเฉพาะรายการที่อาจมีข้อมูลเก่าในบริบทเฉพาะที่ สิ่งนี้จะช่วยให้กราฟวัตถุของคุณ (และดังนั้นการใช้หน่วยความจำ) ในการตรวจสอบและจะดีกว่าการวนลูป-registeredObjectsและตรวจสอบ objectIDs เพื่อดูว่าวัตถุมีข้อบกพร่องในบริบทของคุณหรือไม่
Sterling Archer

4

objectWithID:เป็นวิธีที่คุณกำลังมองหาและเป็นวิธีที่แนะนำในการดำเนินการนี้ objectWithID:จะใช้ NSManagedObjectContext อย่างมีประสิทธิภาพเพื่อดึงวัตถุให้มากที่สุดเท่าที่จำเป็นเท่านั้นซึ่งแตกต่างจากวิธีการอื่น ๆ ในการทำเช่นนี้ objectWithID:จะใช้ข้อมูลในหน่วยความจำอย่างถูกต้องในบริบทหลักผู้ประสานงานการจัดเก็บถาวรและที่เก็บถาวรเองก่อนที่จะไปที่หน่วยเก็บข้อมูลสำรอง

เนื้อหานี้กล่าวถึงในเชิงลึกในเซสชันWWDC 2012 "Core Data Best Practices"


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.