CoreDataСутність "А" має відношення "один до багатьох" до колекції CoreDataзаписів "Б", використовуючи правило каскадного видалення.
В iCloudоточенні, поки пристрій 1 показує детальне подання одного із записів "B", пристрій 2 видаляє запис "A".
Коли NSPersistentStoreDidImportUbiquitousContentChangesNotificationсповіщення надійшло на пристрій 1, його делегат програми викликає, mergeChangesFromContextDidSaveNotificationа потім транслює внутрішнє сповіщення, яке фіксується контролером перегляду, показуючи деталі запису "B" (код використовує performBlockтам, де потрібно).
Однак, хоча запис "А" дійсно анульований, коли контролер подання деталей отримує внутрішнє сповіщення, запис "Б" все ще існує як дійсний CoreDataоб'єкт. Здається, правило Каскаду ще не завершило свою роботу. Тому контролер перегляду на пристрої 1 не знає про видалення, що може призвести до несподіваних результатів.
mergeChangesFromContextDidSaveNotification здається, повертається передчасно, коли базові дані були об’єднані, але правило Каскаду ще не завершено.
Я намагався оновити запис "B", коли сповіщення надходить, тимчасово встановлюючи stalenessIntervalнульовий контекст керованого об'єкта, щоб кешований об'єкт не використовувався, але я все ще отримую дійсний запис "B" з магазину.
Перевірка на наявність nullзапису "А" на даний момент не є варіантом, оскільки ситуація є дещо складнішою, ніж я описав тут, і нульовий запис "А" може бути дійсним у деяких випадках.
Я намагався ввести затримку після об’єднання змін і перед тим, як надіслати внутрішнє сповіщення контролерам перегляду. Я з’ясував, що затримка на 2 секунди не допомагає, але затримка на 10 секунд працює.
Але я не хочу покладатися на цю затримку. Це тестове середовище без великої кількості даних, і я не знаю, що буде у виробничому середовищі. Покладатися на експериментальну затримку, здається, не слід робити.
Чи є щось правильно? Або для початку я роблю щось не так?