Создать сеттер только в Swift
Когда я создаю сеттер, такой:
var masterFrame:CGRect{
set{
_imageView.frame = newValue
_scrollView.frame = newValue
}
}
Это заставило меня сделать добытчик, чего я не хочу делать.
Есть ли способ создать сеттер в Swift без геттера?
Ответы
Ответ 1
Только свойство set не похоже на то, что оно имеет большой смысл. Вероятно, вы должны использовать метод для этого.
Или просто сделайте компилятор счастливым и добавьте получателя, который вы никогда не вызываете:
get {
return _imageView.frame
}
Ответ 2
В docs:
Геттер используется для чтения значения, а сеттер используется для записи Значение. Предложение setter является необязательным, и когда только геттер необходимо, вы можете опустить оба предложения и просто вернуть запрошенные непосредственно, как описано в "Только для чтения". Но если вы предоставляете предложение setter, вы также должны предоставить getter пункт.
Ответ 3
Ну, если бы мне действительно нужно, я бы использовал это.
Компилятор Swift поддерживает некоторые атрибуты в @available(*, unavailable)
получения, поэтому вы можете использовать @available(*, unavailable)
:
public subscript(index: Int) -> T {
@available(*, unavailable)
get {
fatalError("You cannot read from this object.")
}
set(v) {
}
}
Это ясно доставит ваше намерение пользователю кода.
Ответ 4
Чтобы иметь свойство "только для сеттера", вы можете просто иметь простую функцию, которая устанавливает значение; например, если у нас есть частное свойство под названием value
, мы можем вызвать вызванный метод setter, configureWithValue(value:String)
, который обновляет свойство, но не разрешает внешний доступ к свойству:
private var value:String
func configureWithValue(value:String) {
self.value = value
}
Ответ 5
Вместо этого используйте didSet:
var masterFrame:CGRect {
didSet {
_imageView.frame = masterFrame
_scrollView.frame = masterFrame
}
}
Ответ 6
Конечно. Вы можете просто вернуть нуль и сделать тип необязательным:
var color: MyColorEnum? {
get { return nil }
set {
switch newValue! {
case .Blue:
view.backgroundColor = UIColor.blueColor()
case .Red:
view.backgroundColor = UIColor.redColor()
}
}
}
В качестве альтернативы вы можете использовать didSet
, чтобы избежать проблемы вместе:
var color: MyColorEnum! {
didSet {
switch color {
case .Blue:
view.backgroundColor = UIColor.blueColor()
case .Red:
view.backgroundColor = UIColor.redColor()
}
}
}
Ответ 7
Вы можете вернуть nil
из get
:
var input: CGRect? {
set(value) {
guard let value = value else { return }
// process the value here
}
get {
return nil
}
}
Ответ 8
Я нашел одно исключение, где мне действительно нравится переменная setter, которая является, когда я передаю закрытие как единственный параметр в методе с единственной целью сохранить его для последующего выполнения.
Я реализую его как метод следующим образом:
typealias ThemeSetter = () -> ()
class Theme {
fileprivate var themeSetters:[ThemeSetter] = []
class var shared: Theme {
struct Singleton {
static let instance = Theme()
}
return Singleton.instance
}
...
func setColor(_ entry:@escaping ThemeSetter) {
entry()
themeSetters.append(entry)
}
}
Затем я могу вызвать метод следующим образом:
Theme.shared.setColor({
self.navigationBar.barTintColor = Theme.shared.gameBarTint
})
Но после закрывающей скобки мне не нравятся тесные парезы, так как у меня может быть много линий в закрытии.
Итак, зная о Trailing Closures, я могу просто изменить код, чтобы выглядеть так:
Theme.shared.setColor() {
self.navigationBar.barTintColor = Theme.shared.gameBarTint
}
Это прекрасно, и это синтаксис, который Apple показывает для трейлинг-закрытий. Поскольку есть только один параметр и минимализм, что я есть, я испытываю соблазн сделать код еще более компактным и уменьшить его до этого:
Theme.shared.setColor {
self.navigationBar.barTintColor = Theme.shared.gameBarTint
}
Это снова показывает, как Apple показывает, что делает Trailing Closures; Кроме того, этот способ обычно используется для какого-то Предиката, где закрытие используется, чтобы сообщить методу, как сделать сортировку, или когда закрытие используется в конце вызова асинхронной функции как закрытие завершения. Я хочу назначить закрытие... Что-то.
Если я заменил метод setColor на переменную, он выглядит так:
var setColor:ThemeSetter? {
didSet {
if setColor != nil {
setColor?()
themeSetters.append(setColor!)
setColor = nil
}
}
}
Теперь вызов выглядит следующим образом:
Theme.shared.setColor = {
self.navigationBar.barTintColor = Theme.shared.gameBarTint
}
Это знак равенства означает всю разницу. Это показывает, что я назначаю закрытие и не запускаю какую-либо функцию, которая использует закрытие, хотя это и происходит.: ') < - нуждается в смайлике здесь.
Заключительные примечания. Это действительно не имеет ничего общего с закрытием, оно просто показывает, как вы можете сделать только переменную setter, за исключением того, что она все равно возвращает нуль. Он не предназначен для защиты класса от доступа пользователя к переменной для чтения, как только настоящий сеттер. Кроме того, прощайте учебник по трейлинг-закрытию и синглтонам.
Я не могу получить достаточно голосов, чтобы быть правильным ответом, но почему правильный ответ: "Нет, вы не можете! Вы должны использовать вызов метода!". Я говорю "Ni", которому нужен весь этот синтаксис. Просто используйте переменную и не читайте ее, или если вы это сделаете, не возвращайте ее. вроде как ответ Рудольфа Адамковича, который получил 0 голосов.