Разница между вычисляемым свойством и набором свойств с замыканием
Я новичок в Swift. В чем разница между вычисляемым свойством и свойством, установленным на замыкание? Я знаю, что вычисляемое свойство пересчитывается каждый раз. Это отличается от закрытия? т.е.
Закрытие:
var pushBehavior: UIPushBehavior = {
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}()
Рассчитано:
var pushBehavior: UIPushBehavior {
get{
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}
}
4 ответа
Первое - это хранимое свойство, которое инициализируется через замыкание. Второе является вычисляемым свойством.
Закрытие инициализации хранимого свойства вызывается один раз и только один раз, но вы можете позже изменить значение хранимого свойства (если вы не замените var
с let
). Это полезно, когда вы хотите инкапсулировать код для инициализации хранимого свойства в одном сжатом блоке кода.
Однако блок вычисляемого свойства вызывается каждый раз, когда вы ссылаетесь на переменную. Это полезно, когда вы хотите, чтобы код вызывался каждый раз, когда вы ссылаетесь на вычисляемое свойство. Обычно вы делаете это, когда вычисляемое свойство необходимо пересчитывать каждый раз, когда вы ссылаетесь на сохраненное свойство (например, пересчитывается из других, возможно, частных, хранимых свойств).
В этом случае вам, несомненно, понадобится сохраненное свойство (первый пример), а не вычисляемое свойство (второй пример). Вероятно, вам не нужен новый объект push-поведения каждый раз, когда вы ссылаетесь на переменную.
Кстати, в вашем первом примере вы внутренне ссылаетесь на то, что он создается лениво. Если вы хотите такое поведение, вы должны использовать lazy
ключевое слово:
lazy var pushBehavior: UIPushBehavior = {
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}()
Если, однако, свойство static
Это автоматически создается лениво.
Закрытие:
//closure
var pushBehavior: UIPushBehavior = {
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}()
Сначала, когда вызывается переменная pushBehavior, выполняется выполнение блока, и значение сохраняется в переменной pushBehavior. после этого всякий раз, когда вы вызываете pushBehavior, эти значения возвращаются.
означает только первый блочный код, выполненный и сохраненный в этой переменной. Кроме того, вы можете хранить значение переменной в любое время, но после этого эти значения возвращаются, но если вы объявите "let", вы не сможете изменить это значение.
Вычисляемая собственность:
var pushBehavior: UIPushBehavior {
get{
let lazilyCreatedPush = UIPushBehavior()
lazilyCreatedPush.setAngle(50, magnitude: 50)
return lazilyCreatedPush
}
}
В вычисляемом свойстве всякий раз, когда вы вызываете переменную pushBehavior, выполняется этот блок и возвращается значение. поэтому каждый раз выполняется блок. и вы не можете объявить переменную как ключевое слово let для переменной pushBehavior.
Таким образом, вы можете использовать этот код в соответствии с вашими требованиями.
Основное отличие состоит в том, что вы не можете назначить что-то вычисляемому свойству, так как оно не имеет установщика. В этом случае замыкание вызывается только один раз, а возвращаемое значение сохраняется в переменной, поэтому, если результат не изменяется с течением времени, более эффективно использовать сохраненную переменную, а не вычисленную.
В общем: вычисленные свойства следует использовать только в том случае, если значение можно быстро получить.
Sidenote: Если вы не изменяете / переназначаете сохраненную переменную, вам следует рассмотреть возможность сделать ее постоянной (let
)
Это не ответ, но стоит упомянуть, что для:
- В хранимых свойствах значение должно быть известно после инициализации. Это происходит либо по умолчанию, либо путем инициализации.
- Значение вычисляемого свойства не вычисляется до тех пор, пока к нему не будет получен доступ
- Значение ленивого загруженного свойства не определено, пока оно не получит доступ
следовательно, для вычисляемых и ленивых переменных вы можете получить доступ self
или хранящиеся свойства без забот.