Pergunta

Estou tentando entender o propósito de o synthesize directiva com a propriedade de nome de substituir.Dizem que eu tenho uma interface definida como a seguir:

@interface Dummy ... {
    UILabel *_dummyLabel;
}

@property (retain, nonatomic) UILabel *dummyLabel;

E no arquivo de implementação, que eu tenho:

@synthesize dummyLabel = _dummyLabel;

Pelo que eu entendo, "dummyLabel" é apenas um alias da variável de instância "_dummyLabel".Existe alguma diferença entre si._dummyLabel e de si mesmo.dummyLabel?

Foi útil?

Solução

Sim. self._dummyLabel é indefinido, no entanto _dummyLabel não é.

A sintaxe do DOT se expande para invocações simples de métodos, por isso não é específico para propriedades. Se você tem um método chamado -(id)someObject, por exemplo, no caso de object.someObject, será como se você escrevesse [object someObject];.

self.dummyLabel  //works
self._dummyLabel //does not work
dummyLabel       //does not work
_dummyLabel      //works
[self dummyLabel];  //works
[self _dummyLabel]; //does not work

Outras dicas

Seu entendimento está incorreto. dummyLabel é o nome da propriedade e é não um alias para a variável de instância - a variável da instância é chamado _dummyLabel. Portanto, o seguinte vale para uma instância de Dummy chamado myObject:

  • [myObject dummyLabel] funciona
  • myObject.dummyLabel funciona
  • [myObject _dummyLabel] falha
  • myObject._dummyLabel falha
  • myObject->dummyLabel falha
  • myObject->_dummyLabel depende da visibilidade do ivar (@public, @private, @protected)
  • [myObject valueForKey: @"dummyLabel"] funciona
  • [myObject valueForKey: @"_dummyLabel"] depende da implementação de +accessInstanceVariablesDirectly (ou seja, funcionará no caso padrão onde +accessInstanceVariablesDirectly retorna YES).

A vantagem de ter outro nome para o IVAR do que para a propriedade é que você pode ver facilmente no código quando está acessando um ou outro - Andre K

Não sou capaz de encontrar um botão 'Comentário', por isso estou tendo que postar como uma 'resposta'.

Só queria expandir o comentário de Andre - sabendo quando você está usando as propriedades sintetizadas versus a variável de baunilha, você sabe (especialmente em caso de setters) quando uma variável está sendo retida/copiada/liberada automaticamente graças ao seu bom setter, vs sendo manipulado à mão.

Obviamente, se você está fazendo as coisas corretamente, provavelmente não precisa da ajuda de um setter para reter/liberar objetos corretamente! Mas também pode haver outros cenários em que se referindo ao seu adars como self.ivar ao invés de _ivar pode ser útil, como quando você está usando setters/getters personalizados em vez dos sintetizados padrão. Talvez toda vez que você modifica uma propriedade, você também deseja armazená -la no NSUserDefaults. Então você pode ter algum código como este:

@interface SOUserSettings : NSObject {

BOOL _autoLoginOn;

}

@property (nonatomic, assign) BOOL autoLoginOn;

@end

@implementation SOUserSettings

@synthesize autoLoginOn = _autoLoginOn;

- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {

   _autoLoginOn = newAutoLoginOnValue;
   [[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:@"UserPrefAutoLoginOn"];
}

@end

Nota: Este é apenas um código ilustrativo, pode haver mil coisas erradas com ele!

Então agora, em seu código, se você tem uma linha que diz _autoLoginOn = YES - Você sabe que não será salvo para nsuserDefaults, enquanto se você usar self.autoLoginOn = YES Você sabe exatamente o que vai acontecer.

A diferença entre _autoLoginOn e self.autoLoginOn é mais do que apenas semântico.

Não vejo grande vantagem de mudar o nome _dummyLabel para dummyLabel

Em alguns ObjC autonomias você tem um tempo difícil de tomada de variáveis de instância invisível para os usuários da classe.Para aderir a alguns (prefixo ou sufixo) no seu variáveis de instância podem tornar claro (ou mais clara) que você não deseja que alguém brincar com o seu variáveis.No entanto, você não quer que lamaçal em suas funções públicas.Isso permite que você tirá-lo.

Ele também pode ser útil se você precisa para manter uma interface de idade com um conjunto de nomes, ao mesmo tempo, como um novo conjunto de APIs com um novo conjunto de nomes (setLastname vs.setSurname).

Post antigo, mas eu acho que é importante mencionar, que é recomendado para acessar as variáveis através de getters e setters (assim, com a notação de ponto).Aceder a um campo diretamente (_ivar) é fortemente recomendado apenas quando o inicializar.

Há algumas boas da Apple artigo:https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

Último parágrafo:

Você deve sempre acessar as variáveis de instância diretamente de dentro um método de inicialização, porque no momento em que a propriedade é definida, o resto do objeto ainda não pode ser totalmente inicializado.Mesmo se você não forneça personalizado métodos de acesso ou sabe de todos os efeitos secundários de dentro de sua própria classe, um futuro subclasse pode muito bem substituir o comportamento.

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