Uma pergunta sobre setter em Objective-C
-
16-09-2019 - |
Pergunta
Este é um exemplo a partir de A-C Objectivo 2.0 linguagem de programação.
Eu estava pensando, na setter no fundo, eu posso usar value = [newValue retain]
em vez de value = [newValue copy]
?
@interface MyClass : NSObject
{
NSString *value;
}
@property(copy, readwrite) NSString *value;
@end
// assume using garbage collection
@implementation MyClass
@dynamic value;
- (NSString *)value {
return value;
}
- (void)setValue:(NSString *)newValue {
if (newValue != value) {
value = [newValue copy];
}
}
@end
Solução
A coisa mais rápida e mais segura a fazer seria adicionar @synthesize value
para o topo da sua implementação, e o compilador irá gerar automaticamente estes métodos.
A questão da cópia vs. manter dobradiças no fato de que você pode ser passado em um NSMutableString, que iria mudar o seu valor. Se você tem um setter para um tipo de 'imutável' (string, conjunto, matriz, dicionário), você precisa usar a semântica copy
. No início isso pode parecer contraditório (por que fazer uma cópia se ele é imutável?), Mas a coisa a perceber é que sua classe quer assumir que é imutável, eo que é passado em não pode realmente ser imutável.
classes NSMutable implementar o seletor copy
retornando uma versão imutável de que eles representam. As classes imutáveis ??(NSString, etc) implementar copy
com uma chamada retain
. Ou seja, eles são muito rápidos.
Seu setter também precisa liberar value
antes de atribuir-lhe um novo valor. O código correto é:
-(void)setValue:(NSString*)newvalue
{
if (value != newvalue)
{
[value release];
value = [newvalue copy];
}
}
Se você tem controle total sobre todas as classes que podem chamar setValue:
e são absolutamente certo que você não vai estar passando em NSMutableString, você pode usar retain
, mas é as melhores práticas para o uso copy
.
Outras dicas
Depende. Se você usar [newValue retain]
, outro objeto pode alterar o valor desse ponteiro NSString
. Normalmente, você não gosta de ter este comportamento.
Não, sua interface diz copy
. Se alguém passa em um NSMutableString, você vai obter resultados muito diferentes dos dois métodos.
método setter:
-(void)setValue:(NSString*)newvalue{
if (_value != newvalue)
{
[_value release];
_value = nil;
_value = [newvalue copy];
}
}