Видеокурсы по изучению языка программирования Swift. Подробнее

ARC в действии

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Приведем пример того, как работает ARC. Наш пример начнем с класса Person, который определяет константное свойство name:

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) инициализируется")
    }
    deinit {
        print("\(name) освобождается")
    }
}

Класс Person имеет инициализатор, который устанавливает name свойство экземпляра и выводит сообщение для отображения того, что идет инициализация. Так же класс Person имеет деинициализатор, который выводит сообщение, когда экземпляр класса освобождается.

Следующий фрагмент кода определяет три переменные класса Person?, который используется для установки нескольких ссылок к новому экземпляру Person в следующих кусках когда. Так как эти переменные опционального типа (Person?, а не Person), они автоматически инициализируются со значением nil, и не имеют никаких ссылок на экземпляр Person.

var reference1: Person?
var reference2: Person?
var reference3: Person?

Теперь вы можете создать экземпляр класса Person и присвоить его одной из этих трех переменных:

reference1 = Person(name: "John Appleseed")
// Выведет "John Appleseed инициализируется"

Обратите внимание, что сообщение "John Appleseed инициализируется" выводится во время того, как вы вызываете инициализатор класса Person. Это подтверждает тот факт, что происходила инициализация.

Так как новый экземпляр класса Person был присвоен переменной reference1, значит теперь существует сильная ссылка между reference1 и новым экземпляром класса Person. Теперь у этого экземпляра есть как минимум одна сильная ссылка, значит ARC держит под Person память и не освобождает ее.

Если вы присвоите другим переменным тот же экземпляр Person, то добавится две сильные ссылки к этому экземпляру:

reference2 = reference1
reference3 = reference1

Теперь экземпляр класса Person имеет три сильные ссылки.

Если вы сломаете две из этих трех ссылок (включая и первоначальную ссылку), присвоим nil двум переменным, то останется одна сильная ссылка, и экземпляр Person не будет освобожден:

reference1 = nil
reference2 = nil

ARC не освободит экземпляр класса Person до тех пор, пока остается последняя сильная ссылка, уничтожив которую мы укажем на то, что наш экземпляр больше не используется:

reference3 = nil
// Выведет "John Appleseed освобождается"
Swift: 
3.0