При переназначении последней сильной ссылки на другой экземпляр когда старый объект становится доступен для уничтожения?
Старый объект становится доступен для уничтожения, когда после переназначения у него не остаётся сильных ссылок. Если прежний экземпляр удерживается другой сильной ссылкой, переназначение одной переменной его не уничтожит.
ARC автоматически увеличивает и уменьшает число сильных владений: новая ссылка сохраняет новый объект, а прежняя ссылка освобождает старый. Когда сильное владение становится последним, объект обычно освобождается в этот момент, а его deinit становится доступен для вызова.
Подсчёт ссылок решает проблему ручного управления памятью: разработчику не нужно явно вызывать операции удержания и освобождения объектов. В Swift это делает компилятор с помощью ARC.
В отличие от трассирующего сборщика мусора, ARC использует информацию о владении объектом. Поэтому освобождение обычно происходит детерминированно после исчезновения последней сильной ссылки, но циклы сильных ссылок ARC самостоятельно не устраняет.
Переназначение сильной переменной затрагивает сразу два объекта: новый должен быть сохранён сильной ссылкой, а старый — освобождён этой переменной. Ошибка в рассуждении часто приводит к неверному выводу, что старый объект уничтожается при любом переназначении.
Если старый экземпляр дополнительно хранится в другой переменной, коллекции, замыкании или связанном объекте, его время жизни продолжается. Если же последняя сильная ссылка является частью цикла владения, объект может не освободиться вовсе.
При присваивании нового экземпляра сильной переменной ARC обеспечивает две операции владения: новый объект получает сильное владение от переменной, а старый теряет владение от неё. Старый экземпляр становится кандидатом на освобождение только после проверки всех остальных сильных ссылок.
После присваивания current = Session("B") экземпляр A не уничтожается: его по-прежнему сильно удерживает backup. Когда backup получает nil, сильных ссылок на A больше нет, поэтому A становится доступен для освобождения и вызывается его deinit.
Важно отличать сильную ссылку от самого факта нахождения переменной в области видимости. Опциональная переменная типа класса тоже владеет объектом, пока содержит ненулевую ссылку, если она не объявлена как weak или иным образом не является заимствованием.
Точный момент машинных операций retain и release может оптимизироваться компилятором. Нельзя строить корректную логику приложения на побочном эффекте от предполагаемого момента deinit; следует явно управлять владением и ресурсами.
Сервис хранит текущую сетевую сессию, а экран временно сохраняет предыдущую сессию для повторной отправки запроса. Разработчик переназначает свойство сервиса и ожидает немедленного освобождения старой сессии, но экран всё ещё держит её сильную ссылку.
Вариант с копированием экземпляра не подходит: экземпляры классов имеют ссылочную семантику, поэтому копируется ссылка на тот же объект. Вариант с weak уменьшает риск лишнего продления времени жизни, но объект может исчезнуть до повторной отправки запроса.
Выбранное решение — явное сильное временное владение до завершения повторной отправки, после чего ссылка обнуляется. Это сохраняет объект ровно на необходимый период и делает границу его времени жизни понятной; если же прежняя сессия не должна владеть объектом, применяется слабая ссылка с обработкой случая nil.
Нет. Обнуление уменьшает количество сильных владений только на единицу. Объект уничтожается лишь после исчезновения последнего сильного владения; ими могут быть другие переменные, элементы коллекций, свойства или захваты замыканий.
Копируется не экземпляр, а ссылка на него. Обе сильные переменные начинают владеть одним объектом, поэтому переназначение одной из них освобождает только её собственное владение. Сам объект продолжает жить, пока остаётся хотя бы одна сильная ссылка.
deinit надёжно использоваться как место освобождения любого ресурса сразу после переназначения?Только если время жизни объекта действительно ограничено последней сильной ссылкой и ресурс принадлежит этому объекту. Наличие других ссылок, циклов, временных владений или взаимодействия с Objective-C может отложить освобождение. Для критичных ресурсов лучше использовать явный протокол управления ресурсом, а deinit оставлять защитным механизмом, а не единственной частью бизнес-логики.