Как сохранённая ссылка на экземплярный метод влияет на время жизни его объекта?
Сохранённая ссылка на экземплярный метод обычно удерживает его экземпляр сильной ссылкой. Поэтому объект не будет уничтожен, пока существует такая ссылка на метод; это может неожиданно продлить его жизнь или создать цикл владения.
ARC автоматизировал ручное управление подсчёком ссылок, но не изменил сам принцип: объект живёт, пока существует хотя бы одна сильная ссылка. Экземплярный метод при извлечении из объекта превращается в вызываемое значение, которому необходимо сохранить контекст вызова — конкретный экземпляр.
Разработчик может передать метод в обработчик событий, очередь или callback и считать, что сохраняется только функция. На практике сохраняется также объект, к которому метод привязан.
Если объект сам хранит этот callback, возникает цикл: объект сильно удерживает callback, а callback сильно удерживает объект. Внешнее обнуление ссылки тогда не приводит к вызову deinit.
Ссылка на экземплярный метод — это не просто адрес машинного кода. Она включает контекст экземпляра, необходимый для доступа к его свойствам и вызова с корректным self. Этот контекст удерживается сильно, если не создан специальный слабый адаптер.
После присваивания screen = nil объект продолжает жить благодаря сохранённой ссылке на render. Обнуление callback удаляет последнюю сильную ссылку на связанный экземпляр, если других владельцев нет.
Сделать саму ссылку на метод слабой напрямую нельзя. Если нужно избежать удержания объекта, создают замыкание с [weak object] и внутри проверяют результат; такое замыкание уже не удерживает объект сильно.
Важно отличать экземплярный метод от статического или свободного метода: у последних нет конкретного self, поэтому они не продлевают время жизни экземпляра.
Экран передаёт render в долгоживущий диспетчер обновлений. Вариант с прямой ссылкой на метод удобен и типобезопасен, но диспетчер будет удерживать экран. Если экран также удерживает диспетчер или зарегистрированный callback, возможен цикл.
Можно явно удалить регистрацию при закрытии экрана. Это даёт предсказуемое владение, но требует дисциплины и обработки всех путей выхода.
Другой вариант — слабый адаптер: он не удерживает экран и безопасно пропускает вызов после его уничтожения. Минус — callback может перестать выполнять работу, поэтому вызывающая сторона должна корректно обрабатывать отсутствие объекта. Для долгоживущих подписок выбран слабый адаптер, а для короткой операции — сильная ссылка на метод с явным временем удаления регистрации.
Нет. Для экземплярного метода сохраняется привязка к конкретному self. Даже если синтактически значение имеет тип замыкания, оно содержит контекст экземпляра и обычно владеет им сильно.
Нет. Прямая ссылка на метод уже содержит сильное владение экземпляром. Слабое свойство объекта, не участвующее в этой ссылке, не меняет её семантику. Нужно создать отдельное замыкание, которое захватывает объект через [weak ...].
После удаления последней сильной ссылки, включая локальную ссылку на callback и связанный с ним контекст экземпляра. Точный момент освобождения может быть оптимизирован ARC и не обязан совпадать с концом лексической области видимости, если значение больше не используется.