Em caso afirmativo, existem diferenças importantes que não estavam presentes ao usar a observação de valores-chave no Objective-C?
swift
key-value-observing
codeperson
fonte
fonte
.initial
. Para uma solução, veja aqui . Eu recomendo ver os documentos da Apple . Foi atualizado recentemente e abrange muitas notas importantes. Veja também a outra resposta deRespostas:
(Editado para adicionar novas informações): considere se o uso da estrutura Combine pode ajudá-lo a realizar o que você queria, em vez de usar o KVO
Sim e não. O KVO trabalha nas subclasses NSObject da mesma forma que sempre. Ele não funciona para classes que não subclasses NSObject. Swift não possui (atualmente pelo menos) seu próprio sistema de observação nativo.
(Veja os comentários sobre como expor outras propriedades como ObjC para que o KVO funcione nelas)
Veja a documentação da Apple para um exemplo completo.
fonte
dynamic
palavra-chave em qualquer classe Swift para ativar o suporte ao KVO.dynamic
palavra - chave vai para a propriedade que você deseja tornar observável pelo valor-chave.dynamic
palavra - chave pode ser encontrada na seção Usando o Swift com cacau e Objective-C da Apple Developer Library .dynamic
palavra - chave para quaisquer propriedades dentro de uma classe que você gostaria de ser compatível com KVO (não adynamic
palavra-chave na própria classe). Isso funcionou para mim!Você pode usar o KVO no Swift, mas apenas para
dynamic
propriedades daNSObject
subclasse. Considere que você queria observar abar
propriedade de umaFoo
classe. No Swift 4, especifiquebar
comodynamic
propriedade em suaNSObject
subclasse:Você pode se registrar para observar alterações na
bar
propriedade. No Swift 4 e no Swift 3.2, isso foi bastante simplificado, conforme descrito em Usando a observação de valores-chave no Swift :Observe que, no Swift 4, agora temos uma digitação forte de caminhos-chave usando o caractere barra invertida (o
\.bar
é o caminho-chave para abar
propriedade do objeto que está sendo observado). Além disso, como ele está usando o padrão de fechamento de conclusão, não precisamos remover manualmente os observadores (quando otoken
escopo está fora do escopo, o observador é removido para nós) nem precisamos nos preocupar em chamar asuper
implementação se a chave não Combine. O fechamento é chamado apenas quando esse observador específico é chamado. Para mais informações, consulte o vídeo da WWDC 2017, What's New in Foundation .No Swift 3, para observar isso, é um pouco mais complicado, mas muito semelhante ao que se faz no Objective-C. Ou seja, você implementaria
observeValue(forKeyPath keyPath:, of object:, change:, context:)
qual (a) garante que estamos lidando com o nosso contexto (e não com algo que nossasuper
instância registrou para observar); e então (b) manuseie ou repasse para asuper
implementação, conforme necessário. E certifique-se de se remover como observador, quando apropriado. Por exemplo, você pode remover o observador quando ele é desalocado:No Swift 3:
Observe que você só pode observar propriedades que podem ser representadas em Objective-C. Assim, você não pode observar genéricos,
struct
tipos Swiftenum
, tipos Swift , etc.Para uma discussão sobre a implementação do Swift 2, veja minha resposta original, abaixo.
O uso da
dynamic
palavra-chave para atingir o KVO comNSObject
subclasses é descrito na seção Observação de valor-chave do capítulo Adotando convenções de design de cacau do guia Usando Swift com cacau e Objective-C :[Observe que essa discussão sobre o KVO foi removida posteriormente do guia Usando Swift com cacau e Objective-C , que foi adaptado para o Swift 3, mas ainda funciona conforme descrito na parte superior desta resposta.]
Vale a pena notar que o Swift possui seu próprio sistema de observação de propriedades nativas , mas isso é para uma classe que especifica seu próprio código que será executado mediante a observação de suas próprias propriedades. O KVO, por outro lado, foi projetado para registrar-se para observar alterações em algumas propriedades dinâmicas de alguma outra classe.
fonte
myContext
e como você observa várias propriedades?context
ponteiro. Ocontext
ponteiro é fornecido ao observador quandoobserveValueForKeyPath:ofObject:change:context:
é chamado. Ocontext
ponteiro pode ser um ponteiro C ou uma referência a objeto. Ocontext
ponteiro pode ser usado como um identificador exclusivo para determinar a alteração que está sendo observada ou para fornecer outros dados ao observador ".options
branco, significa apenas que o valorchange
não incluirá o valor antigo ou o novo (por exemplo, você pode obter o novo valor referenciando o próprio objeto). Se você apenas especificar.new
e não.old
, significa quechange
incluirá apenas o novo valor, mas não o valor antigo (por exemplo, muitas vezes você não se importa com o que o valor antigo era, mas apenas com o novo valor). Se você precisarobserveValueForKeyPath
passar o valor antigo e o novo, especifique[.new, .old]
. Bottom line,options
apenas especifica o que está incluído nochange
dicionário.Sim e não:
Sim , você pode usar as mesmas APIs KVO antigas no Swift para observar objetos Objective-C.
Você também pode observar as
dynamic
propriedades dos objetos Swift herdados deNSObject
.Mas ... Não , não é fortemente tipado como você poderia esperar do sistema de observação nativo Swift.
Usando Swift com cacau e Objective-C | Observação do valor-chave
Não , atualmente não existe um sistema de observação de valores embutido para objetos Swift arbitrários.
Sim , existem Observadores de Propriedade embutidos , que são fortemente tipados.
Mas ... Não, eles não são o KVO, pois permitem apenas observar as propriedades dos objetos, não suportam observações aninhadas ("caminhos-chave") e você precisa implementá-las explicitamente.
A linguagem de programação rápida | Observadores de propriedades
Sim , você pode implementar a observação explícita de valores, que será fortemente digitada, além de permitir a adição de vários manipuladores de outros objetos, e até dar suporte a aninhamento / "caminhos de chave".
Mas ... Não , não será o KVO, pois funcionará apenas para propriedades que você implementa como observável.
Você pode encontrar uma biblioteca para implementar esse valor observando aqui:
Observable-Swift - KVO for Swift - Value Observing and Events
fonte
Um exemplo pode ajudar um pouco aqui. Se eu tiver uma instância
model
da classeModel
com atributosname
estate
puder observá-los com:Alterações nessas propriedades acionarão uma chamada para:
fonte
Sim.
O KVO requer despacho dinâmico, portanto, basta adicionar o
dynamic
modificador a um método, propriedade, subscrito ou inicializador:dynamic var foo = 0
O
dynamic
modificador garante que as referências à declaração sejam despachadas e acessadas dinamicamenteobjc_msgSend
.fonte
Além da resposta de Rob. Essa classe deve herdar de
NSObject
, e temos 3 maneiras de acionar alterações de propriedadeUse
setValue(value: AnyObject?, forKey key: String)
deNSKeyValueCoding
Use
willChangeValueForKey
edidChangeValueForKey
deNSKeyValueObserving
Use
dynamic
. Consulte Compatibilidade do tipo SwiftE getter e setter de propriedade são chamados quando usados. Você pode verificar ao trabalhar com o KVO. Este é um exemplo de propriedade computada
fonte
Visão geral
É possível usar
Combine
sem usarNSObject
ouObjective-C
Disponibilidade:
iOS 13.0+
,macOS 10.15+
,tvOS 13.0+
,watchOS 6.0+
,Mac Catalyst 13.0+
,Xcode 11.0+
Nota: Precisa ser usado apenas com classes e não com tipos de valor.
Código:
Versão Swift: 5.1.2
Resultado:
Referir:
fonte
Atualmente, o Swift não suporta nenhum mecanismo interno para observar alterações de propriedades de objetos que não sejam 'self'; portanto, não, ele não suporta o KVO.
No entanto, o KVO é uma parte tão fundamental do Objective-C e do Cocoa que parece bastante provável que seja adicionado no futuro. A documentação atual parece implicar isso:
Usando Swift com cacau e Objective-C
fonte
Uma coisa importante a mencionar é que, após atualizar o seu Xcode para 7 beta, você pode receber a seguinte mensagem: "O método não substitui nenhum método da superclasse" . Isso é devido à opcionalidade dos argumentos. Certifique-se de que seu manipulador de observação tenha exatamente a seguinte aparência:
fonte
Isso pode ser útil para poucas pessoas -
Eu usei o KVO dessa maneira no Swift 3. Você pode usar esse código com poucas alterações.
fonte
Outro exemplo para quem encontra um problema com tipos como Int? e CGFloat ?. Você simplesmente define sua classe como uma subclasse de NSObject e declara suas variáveis da seguinte maneira, por exemplo:
fonte