Когда объект удаляется из памяти в системе с подсчётом ссылок (ARC)?

Ответ

Объект удаляется (деаллоцируется) в тот момент, когда его счетчик сильных (strong) ссылок достигает нуля. В ARC (Automatic Reference Counting) компилятор автоматически вставляет вызовы retain и release.

Типичные сценарии:

  1. Локальной переменной выходит из области видимости.
  2. Свойству класса или другой сильной ссылке присваивается nil или новый объект.
  3. Массив, словарь или другая коллекция, содержащая объект, удаляется или очищается.
  4. Цикл сильных ссылок (retain cycle) предотвращает обнуление счетчика, вызывая утечку памяти.

Пример:

class MyClass {}

func example() {
    var strongRef: MyClass? = MyClass() // Retain count = 1
    weak var observer = strongRef       // Weak ссылка НЕ увеличивает счетчик

    strongRef = nil // Retain count становится 0 -> объект немедленно удаляется.
    // Ссылка `observer` автоматически становится `nil`.
}

Важно: Само удаление из памяти может произойти немедленно или быть отложенным, но логически объект считается несуществующим с момента обнуления счетчика.

Ответ 18+ 🔞

А, ну это ж классика, блядь! Сидишь такой, думаешь — а когда эта штука, на которую я пялился, наконец-то сдохнет? Так вот, слушай сюда, распиздяй.

Объект отправляется на тот свет, в цифровую преисподнюю, ровно в тот момент, когда счётчик его сильных ссылок падает до нуля. Вообще, это ARC, ёпта, такая магия компилятора — он сам, хитрая жопа, раскидывает retain и release по коду, как будто конфетти на похоронах.

Типичные сценарии, когда всё накрывается медным тазом:

  1. Локальная переменная вышла за скобки — и всё, пиздец, приехали. Область видимости кончилась, а с ней и жизнь объекта.
  2. Ты взял и прихуярил своему свойству nil или новый объект. Старый-то остался не у дел, сиротой, и его счётчик тут же обнулили. Бывай, дружок.
  3. Массив, словарь или ещё какая коллекция, где этот объект тусовался, пошла под нож — удалили её или очистили. Всех жильцов — нахуй, в небытие.
  4. А вот это самый пиздец — цикл сильных ссылок. Два чувака держатся друг за друга так крепко, что никто не может упасть в могилу. И сидят они там, призраки, память жрут. Утечка, блядь, классическая.

Смотри, как это выглядит в деле, на примере:

class MyClass {} // Вот наш бедолага, будущий покойник.

func example() {
    var strongRef: MyClass? = MyClass() // Родился! Счётчик = 1.
    weak var observer = strongRef       // Слабая ссылка — это как подглядывать в замочную скважину, не увеличивая счётчик.

    strongRef = nil // А тут мы взяли и кинули основную верёвку. Счётчик стал 0 -> объект мгновенно деаллоцируется.
    // И ссылка `observer`, хитрая сука, тут же сама становится `nil`. Призраков не видно.
}

Важный нюанс, ёбана: Само физическое удаление из памяти может случиться сразу или чуть позже, система там себе потирает руки. Но логически-то, с точки зрения твоего кода, объект считается полностью мёртвым с того самого момента, как счётчик обнулился. Всё, приплыли. Можно ставить крест.