Мы иногда слышим: «Swift не выполняет классическую (отслеживание) GC, он использует ARC».
Но я не уверен, что в семантике Swift есть что-то, что требует подсчета ссылок. Кажется, что можно использовать собственный компилятор Swift и среду выполнения, чтобы использовать трассировку GC.
Так что же такое «счетчик ссылок» в Swift? Реализация Apple или сам язык? Существуют ли части языка или библиотеки, которые так сильно поддерживают ARC, что мы можем использовать этот ярлык для самого языка?
источник
deinit
в качестве ключевого слова и связанная с ним семантика действительно являются тем, что делает подсчет ссылок прямо в языке, а не в реализации.Чи ответил на конкретный вопрос в теле о swift, этот ответ отвечает на более общий вопрос в заголовке.
GC подсчета ссылок и GC трассировки предоставляют программисту различные гарантии.
Подсчет ссылок обеспечивает детерминизм в месте в потоке программы, где объект уничтожается, что может быть важно, если у объекта есть ограниченные ресурсы, которые должны быть быстро освобождены. С другой стороны, он не может справиться с циклами «сильных» ссылок.
Это зависит от спецификации отдельного языка, что, если какие-либо характеристики гарантированы, и, следовательно, какие варианты доступны для совместимой реализации.
источник
Вы можете взять язык, известный как Swift, и переименовать его в «Swift with ARC». Затем вы можете создать новый язык под названием «Swift with GC» с точно таким же синтаксисом, но с меньшим количеством гарантий о том, когда объекты освобождаются.
В Swift с ARC, если счетчик ссылок равен 0, объект будет идти. При сборке мусора, если у вас есть слабая ссылка, вы можете присвоить эту слабую ссылку сильной ссылке, чтобы «восстановить» объект. (В Swift, если число ссылок равно 0, слабые ссылки равны нулю); это серьезная разница.
И, конечно же, Swift с ARC гарантирует, что уничтожение последнего счетчика ссылок немедленно освободит объект. Например, у вас может быть класс FileWriter, в котором вам не разрешено иметь два экземпляра, записывающих в один и тот же файл одновременно. В Swift с ARC вы можете сказать oldWriter = nil; newWriter = FileWriter (...), и вы будете знать, что новый FileWriter создается только после удаления старого (если вы не сохранили другую ссылку); в Swift с GC это не сработает.
Другое отличие состоит в том, что в «Swift with ARC» объекты, на которые ссылаются только через циклы сильных ссылок, но которые на самом деле не достижимы, гарантированно не освобождаются.
источник