Я понимаю, что установить и получить для вычисляемых свойств (без поддержки сохраненных свойств )
если вы исходите из Objective-C, имея в виду, что соглашения об именах изменились. В Swift iVar или переменная экземпляра называется сохраненным свойством
Пример 1 (свойство только для чтения) - с предупреждением:
var test : Int {
get {
return test
}
}
Это приведет к предупреждению, потому что это приведет к рекурсивному вызову функции (геттер вызывает сам себя). Предупреждение в этом случае «Попытка изменить 'test' в своем собственном геттере".
Пример 2. Условное чтение / запись - с предупреждением
var test : Int {
get {
return test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
//(prevents same value being set)
if (aNewValue != test) {
test = aNewValue
}
}
}
Аналогичная проблема - вы не можете сделать это, так как он рекурсивно вызывает сеттер. Также обратите внимание, что этот код не будет жаловаться на инициализаторы, так как нет сохраненного свойства для инициализации .
Пример 3. Чтение / запись вычисляемого свойства - с резервным хранилищем
Вот шаблон, который позволяет условную установку фактического сохраненного свойства
//True model data
var _test : Int = 0
var test : Int {
get {
return _test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
if (aNewValue != test) {
_test = aNewValue
}
}
}
Заметка . Фактические данные называются _test (хотя это могут быть любые данные или комбинация данных). Обратите также внимание на необходимость предоставления начального значения (в качестве альтернативы вам необходимо использовать метод init), поскольку _test на самом деле является переменной экземпляра.
Пример 4. Использование воли и набора
//True model data
var _test : Int = 0 {
//First this
willSet {
println("Old value is \(_test), new value is \(newValue)")
}
//value is set
//Finaly this
didSet {
println("Old value is \(oldValue), new value is \(_test)")
}
}
var test : Int {
get {
return _test
}
set (aNewValue) {
//I've contrived some condition on which this property can be set
if (aNewValue != test) {
_test = aNewValue
}
}
}
Здесь мы видим, что willSet и didSet перехватывают изменение фактического сохраненного свойства. Это полезно для отправки уведомлений, синхронизации и т. Д. (См. Пример ниже)
Пример 5. Конкретный пример - контейнер ViewController
//Underlying instance variable (would ideally be private)
var _childVC : UIViewController? {
willSet {
//REMOVE OLD VC
println("Property will set")
if (_childVC != nil) {
_childVC!.willMoveToParentViewController(nil)
self.setOverrideTraitCollection(nil, forChildViewController: _childVC)
_childVC!.view.removeFromSuperview()
_childVC!.removeFromParentViewController()
}
if (newValue) {
self.addChildViewController(newValue)
}
}
//I can't see a way to 'stop' the value being set to the same controller - hence the computed property
didSet {
//ADD NEW VC
println("Property did set")
if (_childVC) {
// var views = NSDictionaryOfVariableBindings(self.view) .. NOT YET SUPPORTED (NSDictionary bridging not yet available)
//Add subviews + constraints
_childVC!.view.setTranslatesAutoresizingMaskIntoConstraints(false) //For now - until I add my own constraints
self.view.addSubview(_childVC!.view)
let views = ["view" : _childVC!.view] as NSMutableDictionary
let layoutOpts = NSLayoutFormatOptions(0)
let lc1 : AnyObject[] = NSLayoutConstraint.constraintsWithVisualFormat("|[view]|", options: layoutOpts, metrics: NSDictionary(), views: views)
let lc2 : AnyObject[] = NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: layoutOpts, metrics: NSDictionary(), views: views)
self.view.addConstraints(lc1)
self.view.addConstraints(lc2)
//Forward messages to child
_childVC!.didMoveToParentViewController(self)
}
}
}
//Computed property - this is the property that must be used to prevent setting the same value twice
//unless there is another way of doing this?
var childVC : UIViewController? {
get {
return _childVC
}
set(suggestedVC) {
if (suggestedVC != _childVC) {
_childVC = suggestedVC
}
}
}
Обратите внимание на использование ОБА вычисленных и сохраненных свойств. Я использовал вычисляемое свойство, чтобы предотвратить установку одного и того же значения дважды (чтобы избежать неприятностей!); Я использовал willSet и didSet для пересылки уведомлений в viewController (см. Документацию UIViewController и информацию о контейнерах viewController)
Я надеюсь, что это поможет, и, пожалуйста, кто-то кричит, если я допустил ошибку где-нибудь здесь!
get
&set
) в основном должно иметь свойство, вычисляемое на основе другого свойства, например, путем преобразования меткиtext
в годInt
.didSet
&willSet
есть, что сказать ... эй, это значение было установлено, теперь давайте сделаем это, например, Наш источник данных был обновлен ... поэтому давайте перезагрузим tableView, чтобы он включал новые строки. В качестве другого примера см . Ответ dfri о том, как вызывать делегатовdidSet