Observando objeto usando objeto proxy
-
29-10-2019 - |
Pergunta
Devo ser capaz de configurar um observador em um objeto proxy, alterar o que o objeto proxy está apontando e ainda ser capaz de observar as mudanças no objeto real?
Um exemplo pode explicar isso melhor. Considere o seguinte.
No cabeçalho:
@interface MyController : NSObject {
MyWidgetModel * aProxyObject;
}
Em uma inicialização ou despertar do método NIB:
-(void)awakeFromNib {
// Init the proxy object. Could be as an empty widget
[aProxyObject addObserver:self
forKeyPath:@"widgetName"
options:NSKeyValueObservingOptionNew
context:nil];
}
Algum outro método que altera o objeto:
-(void)changeWidget:(MyWidgetModel *)aNewWidget {
aProxyObject = aNewWidget;
}
Isso não dispara nenhuma alteração no aNewWidget
. No entanto, se eu mover o addObserver
para depois da atribuição da seguinte maneira, ele funcionará:
-(void)changeWidget:(MyWidgetModel *)aNewWidget {
[aProxyObject removeObserver:self forKeyPath:@"widgetName"];
aProxyObject = aNewWidget;
[aProxyObject addObserver:self
forKeyPath:@"widgetName"
options:NSKeyValueObservingOptionNew
context:nil];
}
Estou assumindo que o primeiro caso não funciona porque o observador está observando o ponteiro de memória da referência do objeto proxy e, como não há objeto no momento em que o observador proxy é adicionado, não tem nada a observar. No entanto, se eu iniciar um widget e observar isso, então atribuo o objeto proxy aNewWidget
, ele ainda não observará as mudanças, a menos que eu adicione o observador após a atribuição (e, claro, criando a necessidade de remover o observador em uma mudança de objeto).
Além disso, o que acontece neste cenário se aNewWidget
for destruído? Como o observador está no proxy, isso nega a necessidade de remover o observador antes de destruir o objeto? (Presumo que não).
Idealmente, gostaria de poder definir o observador no proxy e trocar qualquer referência de widget que eu quiser para o objeto de proxy, sem ter que me preocupar em adicionar e remover o observador, a menos que a classe MyController
vá embora, na qual caso eu pudesse lidar com a remoção do observador no desalocador.
Qualquer ajuda / comentários / conselhos apreciados.
Solução
O keyPath deve ser compatível com KVC.Então, aqui está o código:
@interface MyController : NSObject {
MyWidgetModel * aProxyObject;
}
@property (nonatomic, retain) MyWidgetModel * aProxyObject;
Não se esqueça de sintetizá-lo no arquivo de implementação.Em seguida, use este código para adicionar o observador:
[self addObserver:self
forKeyPath:@"aProxyObject"
options:NSKeyValueObservingOptionNew
context:nil];
Verifique minha edição.Eu mudei a atribuição para reter.Talvez seja melhor para você.Você deve tentar escolher o melhor para você.Só quero dizer que isso não importa no KVO.