Meu entendimento é que set e get são para propriedades computadas (sem suporte de propriedades armazenadas )
se você for de um Objective-C, tenha em mente que as convenções de nomenclatura foram alteradas. No Swift, uma iVar ou variável de instância é denominada propriedade armazenada
Exemplo 1 (propriedade somente leitura) - com aviso:
var test : Int {
get {
return test
}
}
Isso resultará em um aviso, pois resultará em uma chamada de função recursiva (o getter chama a si mesmo). O aviso neste caso é "Tentativa de modificar 'teste' dentro de seu próprio getter".
Exemplo 2. Leitura / gravação condicional - com aviso
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
}
}
}
Problema semelhante - você não pode fazer isso , pois está chamando recursivamente o setter. Além disso, observe que este código não irá reclamar de nenhum inicializador, pois não há propriedade armazenada para inicializar .
Exemplo 3. Propriedade Computada de Leitura / Gravação - com Armazenamento de Suporte
Aqui está um padrão que permite a configuração condicional de uma propriedade armazenada real
//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
}
}
}
Nota Os dados reais são chamados _test (embora possam ser quaisquer dados ou combinação de dados). Observe também a necessidade de fornecer um valor inicial (como alternativa, você precisa usar um método init) porque _test é na verdade uma variável de instância
Exemplo 4. Usando vontade e definir
//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
}
}
}
Aqui vemos willSet e didSet interceptando uma alteração em uma propriedade armazenada real. Isso é útil para enviar notificações, sincronização etc ... (veja o exemplo abaixo)
Exemplo 5. Exemplo concreto - container 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
}
}
}
Observe o uso de ambas as propriedades computadas e armazenadas. Eu usei uma propriedade computada para evitar definir o mesmo valor duas vezes (para evitar que coisas ruins aconteçam!); Eu usei o willSet e o didSet para encaminhar notificações para o viewControllers (consulte a documentação do UIViewController e informações sobre os contêineres do viewController)
Espero que isso ajude, e por favor alguém grite se eu cometi um erro em qualquer lugar aqui!
get
&set
) consiste basicamente em ter uma propriedade calculada com base em outra propriedade, por exemplo, converter um rótulotext
em um anoInt
.didSet
&willSet
existem para dizer ... ei, esse valor foi definido, agora vamos fazer isso, por exemplo, Nosso dataSource foi atualizado ... então vamos recarregar o tableView para incluir novas linhas. Para outro exemplo ver a resposta de DFRI sobre como chamar os delegados emdidSet