Переменная экземпляра, instance variable, ivar
Суть
Переменная экземпляра (ivar) — данные, которые хранит каждый объект отдельно: у двух экземпляров Person свои name и age, изменение одного не задевает другой. Термин «ivar» пришёл из Objective-C; в Swift то же самое называется stored property.
Objective-C: ivar и @property (legacy)
@interface Person : NSObject {
NSString *_name; // ivar, объявленный явно (старый стиль)
}
@property (nonatomic, copy) NSString *email; // компилятор синтезирует _email
@end
@propertyобъявляет пару getter/setter; с автосинтезом компилятор сам создаёт ivar с подчёркиванием (_email).- Внутри класса к ivar обращались напрямую (
_email), снаружи — черезself.email. Вinitиdeallocрекомендовали использовать ivar, чтобы не вызывать переопределённые сеттеры и KVO. - Атрибуты
strong/weak/copy/atomicописывали семантику владения.
Swift: stored и computed properties
final class Person {
var name: String // stored property — «ivar» в Swift
var email = "" // со значением по умолчанию
lazy var greeting = "Hi, \(name)" // создаётся при первом обращении
var initials: String { String(name.prefix(1)) } // computed — памяти нет
var age = 0 {
didSet { print("age: \(oldValue) -> \(age)") }
}
init(name: String) { self.name = name }
}
let a = Person(name: "Ann"), b = Person(name: "Bob")
b.age = 30 // age: 0 -> 30; у a свой набор свойств
print(a.age, b.age) // 0 30
- Stored property занимает память в каждом экземпляре; computed — нет, это пара методов.
lazy varинициализируется при первом обращении (не потокобезопасно для классов).- Property observers
willSet/didSetзаменяют переопределение сеттеров. - Доступ напрямую к ivar в Swift невозможен — только через свойство; для
@objc-классов компилятор по-прежнему создаёт ivar, но это деталь реализации. - Все stored properties должны быть инициализированы до конца
init— компилятор проверяет это.
Чем отличается от других переменных
- Локальная — живёт в вызове функции.
- Статическая — одна на тип.
- Экземпляра — одна на каждый объект, живёт вместе с ним; для класса — в куче, для struct — внутри значения (на стеке или внутри контейнера).
На что смотрит интервьюер
В Objective-C-контексте: разницу между _ivar и self.property и почему в init пишут _name = name. В Swift: stored vs computed, lazy, observers и то, что struct с let-свойствами полностью неизменяем.