Прежде всего, давайте будем знать, что ответы на эти вопросы - все детали реализации, на которые мы должны вообще не полагаться.Теперь перейдем к ответам:
Правда ли, что ARC хранит количество неподтвержденных ссылок на объект?
Да, это правда.Каждый объект имеет три контрольных счета: сильный счет, счетчик не владеющих и слабый счет.
Счет сильный всегда сохраняется (но хранится с настройкой -1, поэтомусохраненный 0 означает счетчик сильных ссылок, а сохраненный 1 означает счетчик сильных ссылок, равный 2 и т. д.)
Неизвестный счетчик также всегда сохраняется с корректировкой+1, который представляет все сильные ссылки и удаляется в конце деинициализации.
Счетчик слабых ссылок сохраняется только после создания первой слабой ссылки на объект.Счетчик слабых ссылок, если он хранится, сохраняется с корректировкой +1, которая представляет все ненужные ссылки и удаляется после освобождения объекта.
Итак, еслисчетчик строгих ссылок объекта достигает 0, а счетчик неопознанных ссылок этого объекта> 0, объект деинициализирован, но не выделен?
Исправить.Объект деинициализирован: deinit
класса объекта и все суперклассы запускаются, и любые свойства объекта, которые сами являются ссылками, устанавливаются в ноль.Однако память объекта не освобождается, потому что заголовок объекта должен оставаться действительным до тех пор, пока не будет уничтожена последняя unowned
ссылка на объект.
И только тогда, когда счетчик сильных и неиспользованных ссылок достигнет 0он распределяется?
Правильно.Объект освобождается, когда количество как сильных, так и не принадлежащих ссылок достигает нуля.Поскольку большинство объектов никогда не ссылаются на ссылки unowned
, обычно это происходит, когда последняя сильная ссылка уничтожается.
Вы не спрашивали о слабых ссылках, но для полноты я объясню ихтакже.Когда на объект (или когда-либо) ссылались слабо, Swift выделяет для объекта то, что он называет «записью боковой таблицы» (или иногда просто «боковой таблицей»).
Еслиу объекта нет боковой таблицы, то сильные и неизвестные значения хранятся непосредственно в объекте, а слабые значения (которые должны быть равны нулю) не сохраняются.
Если объект имееттаблица сторон, затем указатель на таблицу сторон хранится в объекте.Сильные, неизвестные и слабые счета и указатель на объект сохраняются в боковой таблице.
Слабая ссылка на объект сохраняется в виде указателя на сторонустол, а не к объекту.Это означает, что объект может быть освобожден (не только деинициализирован), даже если на него все еще имеются слабые ссылки.
Боковая таблица освобождается, когда объект освобождается , если нет слабыхссылки на объект.Если все еще имеются слабые ссылки, объект освобождается, но дополнительная таблица остается выделенной.Когда последняя слабая ссылка на освобожденный объект уничтожается, боковая таблица освобождается.
Обратите внимание, что слабые ссылки не устанавливаются равными nil (уничтожаются) немедленно, когда объект Swift деинициализирован или освобожден!Слабая ссылка на деинициализированный объект устанавливается на ноль только тогда, когда программа пытается загрузить ссылку, или когда контейнер слабой ссылки деинициализирован.(Я имею в виду под «контейнером», например, когда объект имеет свойство weak var
. Объект является контейнером ссылки weak var
.)
Большой комментарий вверх RefCount.h
в исходном коде Swift объясняет все эти детали и многое другое.
PS TВот еще один вид ссылок, unowned(unsafe)
, который не регулирует количество ссылок.Вы должны избегать такого рода ссылок, если это вообще возможно (и избегание почти всегда возможно).