Làm cách nào để lấy đối tượng Dữ liệu cốt lõi từ ID đối tượng cụ thể?


120

Tôi có thể dễ dàng lấy ID của đối tượng trong Dữ liệu cốt lõi bằng cách sử dụng mã sau:

NSManagedObjectID *moID = [managedObject objectID];

Tuy nhiên, có cách nào để lấy một đối tượng ra khỏi kho dữ liệu cốt lõi bằng cách cấp cho nó một ID đối tượng cụ thể không? Tôi biết rằng tôi có thể làm điều này bằng cách sử dụng NSFetchRequest, như sau:

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

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

Tuy nhiên, tôi muốn làm điều đó theo cách không bắt đầu yêu cầu tìm nạp của chính nó. Có ý kiến ​​gì không?


Nhưng với cách yêu cầu tìm nạp, bạn có thể đặt các thuộc tính hoặc quan hệ được tìm nạp trước, điều này sẽ mang lại cho bạn hiệu quả tuyệt vời thay vì nhiều truy vấn hơn khi bạn truy cập mọi thứ.
malhal

Câu trả lời:


208

Bạn muốn:

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

Tìm nạp đối tượng từ cửa hàng có ID đó hoặc nil nếu nó không tồn tại.

(Hãy lưu ý: có hai phương pháp trên NSManagedObjectContext với những cái tên có vẻ giống nhau đã khiến tôi gặp khó khăn. Để giúp giữ chúng thẳng thắn, đây là những gì hai phương pháp còn lại làm:

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

... sẽ tạo một đối tượng lỗi với objectID được cung cấp, cho dù đối tượng đó có thực sự tồn tại trong cửa hàng hay không. Nếu nó không tồn tại, bất kỳ thứ gì gây ra lỗi sẽ không thành công trừ khi bạn chèn đối tượng trước bằng NSManagedObjectContext's insertObject:. Cách sử dụng duy nhất mà tôi tìm thấy cho việc này là sao chép các đối tượng từ cửa hàng sang cửa hàng trong khi vẫn bảo toàn các ObjectID.

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

... sẽ trả về đối tượng có ID đó, nếu nó đã được tìm nạp từ cửa hàng bởi ManagedObjectContext này. Nếu ai biết phương pháp này hữu ích cho điều gì, xin vui lòng bình luận.)

[eta .: Một sự khác biệt quan trọng khác giữa phương pháp đầu tiên và hai phương pháp kia là existingObjectWithID:error:không bao giờ trả về lỗi; nó luôn tìm nạp toàn bộ đối tượng cho bạn. Nếu bạn đang cố gắng tránh điều đó (ví dụ: làm việc với một đối tượng đắt tiền để tìm mua với tài sản có đốm màu lớn), bạn phải khéo léo với objectWithID:hoặc objectRegisteredForID:, không gây ra lỗi; hoặc sử dụng yêu cầu tìm nạp được định cấu hình đúng.]


11
-(NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectIDcó thể hữu ích khi bạn chỉ muốn xem liệu một đối tượng đã tồn tại trong ngữ cảnh và không muốn tìm nạp nó hay không.
Tony

Tình huống của tôi. Trên -tableView:didSelectRowAtIndexPath: UIAlertView có hiển thị có / không. Trên "có" - có một số công việc với đối tượng. Tôi sử dụng NSFetchedResultsController+ cập nhật CoreData nền từ điều khiển từ xa. Vì vậy, tôi không thể lưu trữ đối tượng: trong khi cảnh báo hiển thị trên màn hình, bộ nhớ có thể được cập nhật và xóa đối tượng. Tôi lưu trữ objectId, sau đó truy xuất nó một lần nữa trong đại biểu cảnh báo. Bởi vì tôi sử dụng NSFetchedResultsController- tất cả các đối tượng cần thiết đã có trong ngữ cảnh vào thời điểm này. Hơn nữa, khi không có đối tượng nào trong ngữ cảnh, CoreData không nên cố gắng tìm nạp vô ích.
kpower

câu trả lời hay, cảm ơn bạn! những tên phương pháp này thực sự phức tạp. thật dễ dàng để lộn xộn mọi thứ với một sai
chó rừng

Câu trả lời tuyệt vời, cảm ơn bạn đã giải thích rõ về objectWithId:- nhu cầu gọi điện insertObjecttrước để ngăn chặn việc tăng ngoại lệ khi cố gắng chữa cháy lỗi thực sự là điều không thể tránh khỏi đối với tôi.
Stanislav Pankevich,

3
objectRegisteredForID:hữu ích khi bạn có danh sách các objectID từ một thao tác trong ngữ cảnh khác và bạn chỉ muốn cập nhật những cái có thể có dữ liệu cũ trong ngữ cảnh cục bộ. Điều này giữ cho đồ thị đối tượng của bạn (và do đó sử dụng bộ nhớ) được kiểm tra và tốt hơn là lặp lại -registeredObjectsvà kiểm tra các ID đối tượng để xem liệu một đối tượng có bị lỗi trong ngữ cảnh của bạn hay không.
Sterling Archer

4

objectWithID:là phương pháp bạn đang tìm kiếm và đó là cách được khuyến nghị để làm điều này. objectWithID:sẽ sử dụng hiệu quả NSManagedObjectContext để chỉ kéo đối tượng ở nhiều cấp độ nếu cần - không giống như một số phương tiện khác để thực hiện việc này. objectWithID:sẽ sử dụng chính xác thông tin trong bộ nhớ trong ngữ cảnh mẹ, trình điều phối lưu trữ liên tục và chính lưu trữ liên tục trước khi chuyển đến lưu trữ dự phòng.

Điều này được đề cập sâu trong phiên WWDC 2012 "Các phương pháp hay nhất về dữ liệu cốt lõi".


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.