Pergunta

Eu poderia estar faltando algo óbvio aqui, mas estou de execução NSCopying em um dos meus objetos.Esse objeto tem variáveis de instância privada que não são expostos através de getters, como eles não devem ser usadas fora do objeto.

No meu implementação de copyWithZone:, Eu preciso alloc/init a nova instância, mas também definir o seu estado para corresponder a instância atual.Eu posso, obviamente, acesso privado actual estado do interior copyWithZone:, mas eu não posso defini-lo para o novo objeto, porque não há acessores para o estado.

Existe um padrão maneira de contornar isso, enquanto ainda mantendo a privacidade de dados intactos?

Obrigado.

Foi útil?

Solução

Primeiro, você deve sempre ter getters, mesmo se eles são privados.Seu objeto deve apenas acesso até mesmo a sua própria ivars usando acessores (exceto em um número muito pequeno de casos).Isso vai lhe poupar uma grande quantidade de sofrimento sobre o gerenciamento de memória.

Segundo Alex, a sugestão de usar -> é um padrão de abordagem, mesmo que isso viola os getters regra acima.Há um pequeno número de exceções para essa regra, e a cópia é um dos.Usando privado setters aqui ainda é razoável (e eu costumava fazê-lo dessa forma exclusivamente), mas eu encontrei, por várias razões, que utilizando -> muitas vezes trabalha fora de limpeza.

Tenha muito cuidado para obter o seu gerenciamento de memória correto.Se você precisa de chamada [super copyWithZone:], e , em seguida, você deve também ler sobre as complexidades da NSCopyObject() e como ele afeta você, mesmo se você não usá-lo sozinho.Eu tenho discutido comprimento em "NSCopyObject() considera-se prejudicial."

Outras dicas

Você pode acessar as variáveis de instância da cópia diretamente.Você usa o mesmo ponteiro de referência de sintaxe que você usaria com uma estrutura (struct).Assim, por exemplo, se sua classe é este:

@interface MyCopyableClass : NSObject {
    int anInstanceVariable;
}
@end

Você pode fazer isso:

- (id)copyWithZone:(NSZone *)zone {
    MyCopyableClass *theCopy = [[[self class] allocWithZone:zone] init];
    theCopy->anInstanceVariable = anInstanceVariable;
    return theCopy;
}

Uma opção é criar um personalizado inicializador de que aceita o privado iVar valores.Assim, você cria ele assim:

-(id) initWithPropertyOne:(SomeClass *) anObject andPropertyTwo:(SomeClass *) anotherObject;

Quando você criar a cópia, basta utilizar o custom inicializador.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top