CoreData + iCloud + Cascade Delete - як з цим працювати?


78

CoreDataСутність "А" має відношення "один до багатьох" до колекції CoreDataзаписів "Б", використовуючи правило каскадного видалення.

В iCloudоточенні, поки пристрій 1 показує детальне подання одного із записів "B", пристрій 2 видаляє запис "A".

Коли NSPersistentStoreDidImportUbiquitousContentChangesNotificationсповіщення надійшло на пристрій 1, його делегат програми викликає, mergeChangesFromContextDidSaveNotificationа потім транслює внутрішнє сповіщення, яке фіксується контролером перегляду, показуючи деталі запису "B" (код використовує performBlockтам, де потрібно).

Однак, хоча запис "А" дійсно анульований, коли контролер подання деталей отримує внутрішнє сповіщення, запис "Б" все ще існує як дійсний CoreDataоб'єкт. Здається, правило Каскаду ще не завершило свою роботу. Тому контролер перегляду на пристрої 1 не знає про видалення, що може призвести до несподіваних результатів.

mergeChangesFromContextDidSaveNotification здається, повертається передчасно, коли базові дані були об’єднані, але правило Каскаду ще не завершено.

Я намагався оновити запис "B", коли сповіщення надходить, тимчасово встановлюючи stalenessIntervalнульовий контекст керованого об'єкта, щоб кешований об'єкт не використовувався, але я все ще отримую дійсний запис "B" з магазину.

Перевірка на наявність nullзапису "А" на даний момент не є варіантом, оскільки ситуація є дещо складнішою, ніж я описав тут, і нульовий запис "А" може бути дійсним у деяких випадках.

Я намагався ввести затримку після об’єднання змін і перед тим, як надіслати внутрішнє сповіщення контролерам перегляду. Я з’ясував, що затримка на 2 секунди не допомагає, але затримка на 10 секунд працює.

Але я не хочу покладатися на цю затримку. Це тестове середовище без великої кількості даних, і я не знаю, що буде у виробничому середовищі. Покладатися на експериментальну затримку, здається, не слід робити.

Чи є щось правильно? Або для початку я роблю щось не так?


Тут більше, ніж здається, оскільки видалення каскаду розповсюджується одразу, що настає першим: processPendingChanges, збереження або закінчення циклу циклу запуску. У звичайних умовах проблема, яку ви описуєте, не повинна існувати.
Свена

- це керований ідентифікатор об’єкта для об’єкта в контролері детального подання в масиві NSDeletedObjectsKey, який постачається з NSPersistentStoreDidImportUbiquitousContentChangesNotification?
ImHuntingWabbits

Це завжди відбувається або це з перервами? Я маю складну ієрархічну структуру і ще не бачив жодного сироти! Ви знову отримуєте сутність B, або, можливо, через те, що ви якось відображаєте її, ви зберігаєте посилання на об’єкт. Що станеться, якщо ви закриєте програму та відкриєте її знову, вона все ще є там?
Duncan Groenewald

3
@Amiram Півтора роки. Ви отримали свою відповідь? :)
блідо-блакитна крапка

Відповіді:


1

З досвіду, прослуховування інших повідомлень, крім NSManagedObjectContextDidSaveNotificationвеликої халепи, може призвести до покладання на властивості, які ще не оновлені. Контролер детального перегляду повинен прослуховувати NSManagedObjectContextDidSaveNotificationсповіщення, які видаються після застосування каскаду. Потім можна кількома способами перевірити, чи дійсний поточний об’єкт чи ні (можна перевірити, nilчи є контекст керованого об’єкта поточним об’єктом, або можна виконати вибірку та перевірити, чи існує об’єкт у сховищі).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.