self.variable e variable difference

Qual é a diferença entre self.myVariable = obj; e myVariable = obj; , quando eu uso @propery / @propery para criar myVariable?

É importante notar que a syntax de pontos é convertida em uma simples chamada objcmsgSend pelo compilador: isto é, que sob ela atua exatamente como uma mensagem enviada ao acessador para aquela variável. Como tal, todos os três dos seguintes são equivalentes:

 self.myVariable = obj; [self setMyVariable:obj]; objc_msgSend(self, @selector(setMyVariable:), obj); 

Naturalmente, isso significa que o uso de syntax de ponto realmente resulta em um envio de mensagem completo, o que significa chamar uma nova function e toda a sobrecarga associada a ela. Em contraste, o uso de atribuição simples (myVariable = obj;) não incorre em nada dessa sobrecarga, mas é claro que só pode ser usado dentro dos methods de instância da class em questão.

A diretiva @synthesize diz ao compilador para gerar acessadores para suas variables ​​membro, de acordo com as especificações dadas na diretiva @property em seu arquivo .h. (Ou seja, se você especificar keep, o setter irá reter a variável, e se você especificar copy, irá copiá-la).

Os acessadores (a menos que você especifique o contrário) sejam nomeados propertyName e setPropertyName.

Usando o. notação (note, não a auto syntax como dito acima) está dizendo que você quer usar os acessadores (uma coisa boa se você está definindo cadeias, e quer garantir que a contagem de retenções esteja correta, por exemplo).

Então, dentro da sua implementação de class:

  • self.bill = fred irá chamar o accessr setBill.
  • bill = fred irá definir fatura para fred diretamente, sem passar pelo acessador.

Uma das diferenças que descobri ao iniciar o desenvolvimento do Cocoa é se eu definir a variável para usar uma syntax @ Property / @ Synthesize e não usei self.myVariable = obj ou [self setMyVariable: obj] mas em vez disso myVariable = obj , o object não é retido se obj for liberado posteriormente. (Assumindo que @Property foi configurado para usar reter).

A razão é que a contagem de retenções não é definida ao usar myVariable = obj e quando o obj é liberado, a contagem é agora zero. (A menos que você o retenha) Mas, usando o acessador, ele fará a contagem para você. (Novamente, supondo que você configurá-lo para usar reter quando foi declarado).

Shyne

Se eu puder adicionar uma nota importante para isso. A resposta acima é incrível, então não vou adicionar ao lado técnico. Mas apenas isso:

Se você criar uma propriedade sintetizada

 @synthesize myProp; 

Sempre use o padrão self.myProp para defini-lo.

 self.myProp = newVal; 

Isso parece muito óbvio, mas é importante. É verdade que simplesmente não há razão para fazer isso, mas até que você realmente entenda como os setters sintetizados são criados, você só quer assumir que tem que usar o self. padrão para definir o valor.

Honesto: isso vai lhe poupar muitas sessões de debug tarde da noite. Violações de access à memory não retidas são simplesmente as piores a serem depuradas.

A syntax self usa o método do acessador, a outra syntax não. Isso pode ser uma grande diferença se o acessador fizer algo mais do que simplesmente atribuir o novo valor. Veja a parte Declared Properties do tutorial do Objective-C.

As outras respostas estão corretas, a diferença é que a notação de ponto faz com que o ivar seja alterado através do acessório e não diretamente.

Até que você saiba o que está fazendo, recomendo que use a notação de ponto (ou seja, self.propertyName = ... ). Cocoa / Obj-C faz muito com codificação de valor-chave e, embora o SDK do telefone não aproveite ao máximo isso (com coisas como ligações), eventualmente isso acontecerá. Acostumar-se a usar os acessadores agora vai lhe poupar muitas dores de cabeça no futuro.

Usar os methods de access também oferece a oportunidade de substituí-los e fornecer mais funcionalidades, caso seja necessário. Simplesmente mudando o valor do ivar, você se rouba dessa capacidade.