Swift readonly external, внутреннее свойство readwrite
В Swift используется обычный способ определения общего шаблона, в котором свойство должно быть внешне readonly, но модифицировано внутри класса (и подклассов), которые его владельцы.
В Objective-C имеются следующие опции:
- Объявить свойство как readonly в интерфейсе и использовать расширение класса для доступа к свойству внутри. Это доступ к сообщениям, поэтому он отлично работает с KVO, атомарностью и т.д.
- Объявить свойство как только для чтения в интерфейсе, но внутренне получить доступ к внутреннему ivar. Поскольку доступ по умолчанию для ivar защищен, это хорошо работает в иерархии классов, где подклассы также смогут изменять значение, но поле в противном случае является только для чтения.
В Java соглашение:
- Объявить защищенное поле и реализовать общедоступный метод get-get-only-only.
Какая идиома для Swift?
Ответы
Ответ 1
Для свойства класса вы можете указать другой уровень доступа, префикс объявления свойства с помощью модификатора доступа, а затем get
или set
между скобками. Например, свойство класса с публичным получателем и частным сеттером будет объявлено как:
private(set) public var readonlyProperty: Int
Рекомендуемое чтение: Getters and Setters
Мартинские соображения относительно уровня доступности все еще действительны, т.е. нет модификатора protected
, internal
ограничивает доступ только к модулю, private
только к текущему файлу и public
без ограничений.
Swift 3 примечания
2 новых модификатора доступа, fileprivate
и open
были добавлены к языку, а private
и public
были слегка изменены:
-
open
применяется только к классам и членам класса: он используется для того, чтобы класс был подклассифицирован или член переопределялся вне модуля, где они определены. public
вместо этого делает класс или член общедоступным, но не наследуемым или переопределяемым
-
private
теперь делает элемент видимым и доступным только из объявляющего объявления, тогда как fileprivate
для всего файла, в котором он содержится
Подробнее здесь.
Ответ 2
В соответствии с @Antonio мы можем использовать одно свойство для доступа в качестве значения свойства readOnly
публично и readWrite
в частном порядке. Ниже приведена моя иллюстрация:
class MyClass {
private(set) public var publicReadOnly: Int = 10
//as below, we can modify the value within same class which is private access
func increment() {
publicReadOnly += 1
}
func decrement() {
publicReadOnly -= 1
}
}
let object = MyClass()
print("Initial valule: \(object.publicReadOnly)")
//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1
object.increment()
print("After increment method call: \(object.publicReadOnly)")
object.decrement()
print("After decrement method call: \(object.publicReadOnly)")
И вот вывод:
Initial valule: 10
After increment method call: 11
After decrement method call: 10