Какими способами можно передать данные с экрана Б обратно на экран А после изменения
Что проверяют
Знаете ли вы несколько механизмов обратной связи между экранами и умеете ли выбрать нужный, не создав утечку памяти. Следом почти всегда спрашивают, почему делегат объявляют weak и что будет с замыканием без [weak self].
Как отвечать
- делегат: протокол с ограничением
AnyObject, на экране Б свойствоweak var delegate, экран А назначает себя при создании Б. Классика UIKit для связи один к одному, когда событий несколько:didSave,didCancel; - замыкание:
var onSave: ((Item) -> Void)?на экране Б, экран А задаёт его перед показом. Меньше кода, чем с протоколом, удобно для одного события. Внутри нужен[weak self]; - async/await: координатор показывает Б и ждёт результат через
withCheckedContinuation, вызывающий код пишетlet item = await pickItem(). Континуацию возобновляют ровно один раз, в том числе при закрытии свайпом; - Combine:
PassthroughSubjectво вью-модели Б, экран А подписывается и хранитAnyCancellable; - unwind segue: для сторибордов, в А объявляется
@IBActionс параметромUIStoryboardSegue, данные берут изsegue.source; - общая модель: оба экрана работают с одним объектом состояния, Б меняет, А наблюдает. В SwiftUI это
@Bindingдля простого значения или общий класс с@Observable(iOS 17+), плюсonDismissуsheet; - NotificationCenter: только когда изменение нужно многим несвязанным получателям.
Хорошо добавить про архитектуру: с координатором результат Б возвращается замыканием в координатор, и экраны ничего не знают друг о друге.
Где спотыкаются
Объявляют делегат сильной ссылкой или захватывают self без [weak self]. Если А хранит ссылку на Б, получается цикл удержания, и экраны не освобождаются.
Решают задачу один к одному через NotificationCenter или синглтон. Работает, но откуда пришли данные, уже не найти, а глобальное состояние мешает тестам.
Перечитывают данные в viewWillAppear экрана А вместо явного возврата результата. С iOS 13 модальный экран в стиле pageSheet при закрытии не вызывает viewWillAppear у А, и обновление не произойдёт.