Ответ 1
Инициализатор ленивых свойств отвечает за инициализацию свойства при первом доступе в режиме чтения. Настройка на nil не влияет на статус инициализации - это просто допустимое значение, которое сохраняет свойство.
Вы можете имитировать ленивую инициализацию с тремя свойствами:
- частный инициализатор, реализованный как вычисленное свойство (или закрытие, если вы предпочитаете)
- свойство частной поддержки, сохраняющее фактическое значение
- не частное свойство, которое вы фактически используете в своем коде
Код выглядит следующим образом:
class MyClass {
private var _myPropInitializer: Int {
return 5
}
private var _myProp: Int?
var myProp: Int? {
get {
if self._myProp == nil {
self._myProp = self._myPropInitializer
}
return _myProp!
}
set {
_myProp = newValue
}
}
}
- свойство initializer возвращает вычисленное значение для переменной, когда оно должно быть инициализировано, что является
5
целым числом в приведенном выше примере -
myProp
- необязательное целое число (для храненияnil
):- в наборе, он сохранит новое значение в свойстве
_myProp
- on get, если
_myProp
-nil
, он вызывает инициализатор, присваивая его_myProp
и возвращает его значение
- в наборе, он сохранит новое значение в свойстве
Если вы хотите повторно использовать этот шаблон, лучше поместить все в класс:
class Lazy<T> {
private let _initializer: () -> T
private var _value: T?
var value: T? {
get {
if self._value == nil {
self._value = self._initializer()
}
return self._value
}
set {
self._value = newValue
}
}
required init(initializer: () -> T) {
self._initializer = initializer
}
}
Примечание: a struct
неприменим, поскольку установка свойства внутри свойства getter недопустима, тогда как в классе это.
Затем вы можете использовать его следующим образом:
class MyTestClass {
var lazyProp: Lazy<Int>
init() {
self.lazyProp = Lazy( { return 5 } )
}
}
Некоторые тесты на детской площадке:
var x = MyTestClass()
x.lazyProp.value // Prints {Some 5}
x.lazyProp.value = nil
x.lazyProp._value // Prints nil
x.lazyProp.value // Prints {Some 5}
Недостатком является то, что вам нужно получить доступ к фактическому свойству как x.lazyProp.value
, а не как x.lazyProp
.