Existe uma diferença entre uma “variável de instância” e uma “propriedade” no Objective-c?

Existe uma diferença entre uma “variável de instância” e uma “propriedade” em Objective-c?

Não tenho muita certeza disso. Eu acho que uma “propriedade” é uma variável de instância que tem methods de access, mas eu posso pensar errado.

Uma propriedade é um conceito mais abstrato. Uma variável de instância é literalmente apenas um slot de armazenamento, como um slot em uma estrutura. Normalmente, outros objects nunca devem acessá-los diretamente. Uma propriedade, por outro lado, é um atributo do seu object que pode ser acessado (soa vago e deve ser). Normalmente, uma propriedade retornará ou definirá uma variável de instância, mas poderá usar dados de vários ou nenhum. Por exemplo:

@interface Person : NSObject { NSString *name; } @property(copy) NSString *name; @property(copy) NSString *firstName; @property(copy) NSString *lastName; @end @implementation Person @synthesize name; - (NSString *)firstName { [[name componentsSeparatedByString:@" "] objectAtIndex:0]; } - (NSString *)lastName { [[name componentsSeparatedByString:@" "] lastObject]; } - (NSString *)setFirstName:(NSString *)newName { NSArray *nameArray = [name componentsSeparatedByString:@" "]; NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]]; self.name = [newNameArray componentsJoinedByString:@" "]; } - (NSString *)setLastName:(NSString *)newName { NSArray *nameArray = [name componentsSeparatedByString:@" "]; NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]]; self.name = [newNameArray componentsJoinedByString:@" "]; } @end 

(Nota: O código acima é buggy na medida em que assume o nome já existe e tem pelo menos dois componentes (por exemplo, “Bill Gates” em vez de apenas “Gates”). Eu senti que a fixação dessas suposições faria o ponto real do código menos claro, então eu só estou apontando para fora aqui, então ninguém inocentemente repete esses erros.)

Uma propriedade é uma maneira amigável de implementar um getter / setter para algum valor, com resources e syntax úteis adicionais. Uma propriedade pode ser apoiada por uma variável de instância, mas você também pode definir o getter / setter para fazer algo um pouco mais dynamic, por exemplo, você pode definir uma propriedade lowerCase em uma string que cria dinamicamente o resultado em vez de retornar o valor de algum membro variável.

Aqui está um exemplo:

 // === In your .h === @interface MyObject { NSString *propertyName; } // ... @property (nonatomic, retain) NSString *propertyName; // === In your .m @implementation === @synthesize propertyName /* = otherVarName */; 

A linha @property define uma propriedade chamada propertyName do tipo NSString * . Isso pode ser obtido / definido usando a seguinte syntax:

 myObject.propertyName = @"Hello World!"; NSLog("Value: %@", myObject.propertyName); 

Quando você atribui ou lê de myObject.propertyName você está realmente chamando methods setter / getter no object.

A linha @synthesize diz ao compilador para gerar esses getter / setters para você, usando a variável de membro com o mesmo nome da propriedade para armazenar o valor (ou otherVarName se você usar a syntax nos comentários).

Juntamente com o @synthesize você ainda pode replace um dos getters / setters definindo o seu próprio. A convenção de nomenclatura para esses methods é setPropertyName: para o setter e propertyName (ou getPropertyName , não padrão) para o getter. O outro ainda será gerado para você.

Na linha @property , você pode definir vários atributos nos parêntesis para a propriedade que podem automatizar itens como segurança de thread e gerenciamento de memory. Por padrão, uma propriedade é atômica, o que significa que o compilador irá @synthesiz chamadas get / set @synthesiz com bloqueios apropriados para evitar problemas de simultaneidade. Você pode especificar o atributo nonatomic para desabilitar isso (por exemplo, no iPhone, você deseja padronizar a maioria das propriedades como nonatomic ).

Existem 3 valores de atributos que controlam o gerenciamento de memory para qualquer @synthesized setters. O primeiro é retain que enviará automaticamente os valores antigos da propriedade e retain os novos valores. Isso é muito útil.

A segunda é a copy que fará com que uma cópia de todos os valores seja passada em vez de retê-los. É uma boa prática usar a copy para NSString porque um chamador poderia passar em um NSMutableString e alterá-lo de baixo de você. copy irá fazer uma nova cópia da input que só você tem access.

O terceiro é assign que faz um ponteiro direto atribuir sem chamar reter / soltar no object antigo ou novo.

Por fim, você também pode usar o atributo readonly para desabilitar o setter da propriedade.

Eu uso propriedades para a parte de interface – onde o object interage com outros objects e variables ​​de instância são coisas que você precisa dentro de sua class – ninguém, mas você deve vê-las e manipulá-las.

Por padrão, uma propriedade readwrite será apoiada por uma variável de instância, que será novamente sintetizada automaticamente pelo compilador.

Uma variável de instância é uma variável que existe e mantém seu valor para a vida do object. A memory usada para variables ​​de instância é alocada quando o object é criado pela primeira vez (por meio de alocação) e liberado quando o object é desalocado.

A menos que você especifique o contrário, a variável de instância sintetizada tem o mesmo nome da propriedade, mas com um prefixo de sublinhado. Para uma propriedade chamada firstName, por exemplo, a variável de instância sintetizada será chamada _firstName.

Anteriormente, as pessoas usavam propriedades publicamente e ivars para uso privado, mas há vários anos você também pode definir propriedades em @implementation para usá-las de maneira privada. Mas eu ainda usaria ivars quando possível, já que há menos letras para digitar, e ele corre mais rápido de acordo com este artigo . Faz sentido, já que as propriedades são “pesadas”: elas devem ser acessadas a partir de getters / setters gerados ou manualmente.

No entanto, em códigos recentes da Apple, os ivars não são mais usados. Eu acho que porque é mais como objc vez de C/C++ , mais é mais fácil usar propriedades com assign , nullable , etc.