Person
, который определяет хранимое свойство name
:
Person
имеет инициализатор, который устанавливает значение свойства name
и выводит сообщение для индикации того, что инициализация происходит. Класс Person
также имеет деструктор, который выводит сообщение, когда объект класса деаллоцируется.
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
Person?
, которые используются для установки множества ссылок на новый объект типа Person
. Так как эти переменные имеют опциональный тип (Person?, а не Person), то они автоматически инициализируются значением nil
, а не какой-то ссылкой на объект типа Person
.
var reference1: Person?
var reference2: Person?
var reference3: Person?
Person
и присвоить ему одной из тех переменных:
reference1 = Person(name: "John Appleseed")
// Выведет "John Appleseed is being initialized"
Заметьте, что сообщение "John Appleseed is being initialized" выводится в момент, когда Вы вызываете инициализатор класса Person
. Это подверждает, что инициализация имела место быть.
Person
был присвоен переменной variable1
, теперь существует сильная ссылка от reference1
к новому объекту Person
. Так как существует хотя быть одна сильная ссылка, то ARC будет гарантированно хранить этот объект Person
в памяти и не будет его деаллоцировать.
reference2 = reference1
reference3 = reference1
Теперь существуют три сильные ссылки на один объект типа Person
.
nil
двум из этих переменных, то останется одна сильная ссылка, а объект Person
не будет деаллоцирован:
reference1 = nil
reference2 = nil
Person
, пока третья и последняя сильная ссылка не будет разбита, в момент чего станет ясно, что Вы больше не используете объект типа Person
:
reference3 = nil
// Выведет "John Appleseed is being deinitialized"
Person
, который Вы создаёте, и деаллоцировать этот объект Person
, когда он больше не будет нужен.
Person
и Apartment
, которые моделируют апартаменты и их постояльцев:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { print("\(name) is being deinitialized") }
}
class Apartment {
let unit: String
init(unit: String) { self.unit = unit }
var tenant: Person?
deinit { print("Apartment \(unit) is being deinitialized") }
}
Каждый объект типа Person
имеет свойство name типа String
и опциональное свойство apartament
с изначальным значением nil
. Свойство apartament
опционально, так как человек не всегда может иметь апартаменты.
Apartment
имеет свойство unit
типа String
и опциональное значение tenant
изначально заданное в nil
. Свойство постояльца опциоально, потому что апартаменты не всегда могут иметь постояльца.
Person
и Apartament
, как это ожидалось.
john
и unit4A
, которым ниже будут заданы конкретные значения типа Person
и Apartment
. Обе этих переменных имеют изначальное значение nil
, что достигается за счёт их опциональности:
var john: Person?
var unit4A: Apartment?
Person
и Apartament
и присвоить их переменных john
и unit4A
:
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
Здесь представлено, как сильные ссылки выглядят после создания и присвоения этих двух объектов. Переменная john
теперь имеет сильную ссылку на новый объект Person
, а переменная unit4A
имеет сильную ссылку на новый объект Apartament
:
john
и unit4A
, так чтобы свойства этих объектов могли быть заданы:
john!.apartment = unit4A
unit4A!.tenant = john
Здесь представлено, как сильные ссылки выглядят после того, как Вы слинкуете эти два объекта вместе:
Person
имеет теперь сильную ссылку на объект Apartment
, а объект Apartment
имеет сильную ссылку на объект Person
. Следовательно, когда Вы разобьете сильные ссылки, удерживаемые переменными john
и unit4A
, то количество ссылок не упадёт в нуль, а объекты не будут деалоцированы ARC:
john = nil
unit4A = nil
Заметьте, что не было вызвано никакого инициализатора, когда Вы установили эти две переменных в nil
. Цикл сильных ссылок мешает объектам Person
и Apartment
быть деалоицированными, что вызывает утечку памяти в Вашем приложении.
Person
и Apartment
остаются и не могут быть разбиты.
john
и unit4A
переменные установлены в nil
: