Observadores de Propriedades
Parte da seção Programação Orientada a Objetos do Journey de Swift da Coddy. Lição 13 de 57.
Um observador de propriedade executa código sempre que uma propriedade armazenada é alterada. didSet é executado logo após o novo valor ser armazenado, e dentro dele oldValue contém o valor anterior:
class Player {
var score = 0 {
didSet {
print("score \(oldValue) -> \(score)")
}
}
}
let p = Player()
p.score = 10
p.score += 5Saída:
score 0 -> 10
score 10 -> 15willSet é executado antes da alteração, com o valor recebido como newValue. Os observadores não são executados quando a propriedade recebe seu valor inicial:
struct Thermostat {
var target = 20 {
willSet { print("changing to \(newValue)") }
didSet { print("changed from \(oldValue)") }
}
}
var t = Thermostat()
t.target = 22Saída:
changing to 22
changed from 20didSet é um bom lugar para manter um valor válido. Atribuir à propriedade dentro do próprio didSet não aciona o observador novamente:
struct Volume {
var level = 5 {
didSet {
if level > 10 { level = 10 }
if level < 0 { level = 0 }
}
}
}
var v = Volume()
v.level = 42
print(v.level)
v.level = -3
print(v.level)Saída:
10
0Os observadores também podem manter um histórico ou atualizar um estado relacionado, mantendo essa lógica próxima à propriedade em vez de espalhá-la pelo código:
class Account {
var history: [Int] = []
var balance = 0 {
didSet { history.append(balance - oldValue) }
}
}
let a = Account()
a.balance = 100
a.balance = 70
print(a.history)Saída:
[100, -30]Desafio
FácilComplete a classe Tank. Sua propriedade armazenada level deve permanecer entre 0 e capacity: adicione um didSet que corrija valores fora desse intervalo e acrescente um aviso low a alerts sempre que o nível corrigido terminar abaixo de 20% da capacidade (e o nível anterior não estivesse baixo).
O código fornecido lê a capacidade e depois altera +n ou -n. Ele imprime o nível após cada alteração e, por fim, alerts: com o número de avisos.
Seu código deve ficar em Tank.swift. main.swift contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
// Código de entrada/saída fornecido: mantenha-o como está
var input: [String] = []
while let line = readLine() { input.append(line) }
let tank = Tank(capacity: Int(input[0])!)
for cmd in input.dropFirst() {
let n = Int(cmd.dropFirst())!
tank.level += cmd.hasPrefix("+") ? n : -n
print(tank.level)
}
print("alerts: \(tank.alerts.count)")
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesMétodos e selfInicializadoresClasses são ReferênciasRevisão - Cartão da Biblioteca4Encapsulamento
Controle de AcessoSomente Leitura ExternaProtegendo o EstadoInicializadores que Podem FalharRevisão - Conta Bancária7Polimorfismo e Genéricos
PolimorfismoConversão de TiposFunções GenéricasTipos GenéricosRevisão - Calculadora de Formas2Structs e Tipos de Valor
StructsSemântica de ValorMétodos MutáveisStruct ou ClasseRecapitulação - Item de Inventário5Herança
SubclassesSobrescrita de métodosInicializadores e superfinal e hierarquiasRecapitulação - Hierarquia de funcionários8Protocolos Padrão
CustomStringConvertibleEquatableComparableHashableRecapitulação - Ordenação Personalizada11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de Livros3Propriedades em Profundidade
Propriedades ComputadasObservadores de PropriedadesMembros EstáticosEnums com MétodosRecapitulação - Registro de TemperaturaPratique por conta própria: Playground de Swift