Quem programa utilizando Orientação a Objetos sabe bem a importância de criar os atributos de uma classe como private e criar os “Accessors” para alterar ou recuperar os valores desses atributos; o Objective-C 2.0 disponibiliza uma maneira muito simples e prática para isso, os “Synthesized Accessor Methods“.
Quando estamos falando de mobile devices (iPhone/iPad) deve-se levar em conta o consumo de memória, e pensando nisso um bom accessor para um atributo nome seria mais ou menos assim:
- (void) setNome: (NSString *) _nome { [nome release]; nome = [[NSString alloc] initWithString: _nome]; } - (NSString *) nome { return nome; }
antes de fazer o set do novo valor, o valor antigo é liberado da memória evitando “vazamentos” indesejáveis.
Para que o compilador realize essa tarefa, nos poupando muito trabalho, primeiro você declara o atributo utilizando a diretiva “@property” na sua interface, e depois na implementação da classe utilizar a diretiva “@synthesize“. Desse modo o compilador vai gerar automaticamente o “getter” e o “setter” do seu atributo.
Nada melhor que um exemplo, vamos começar com a interface “MyClass1.h”:
#import <Foundation/Foundation.h> @interface MyClass1 : NSObject { int aInt; NSString *nome; } @property int aInt; @property (copy, nonatomic) NSString *nome; @end
a diretiva “@property” aceita alguns parâmentros para informar ao compilador como criar o “Accessor“, no nosso caso queremos que seja feita uma cópia no setter do atributo (como no exemplo acima), então usamos o parâmetro “copy“, e ainda o “nonatomic” pois não queremos que o getter faça um “retain” ou um “autorelease” antes que ele retorne o valor do atributo (mais sobre o “retain” e o “autorelease” nos próximos artigos).
agora o “MyClass1.m”:
#import "MyClass1.h" @implementation MyClass1 @synthesize aInt; @synthesize nome; @end
não está faltando código, é só isso mesmo.
e finalmente um programa que faz a chamada:
#import <Foundation/Foundation.h> #import "MyClass1.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; MyClass1 * m = [[MyClass1 alloc] init]; [m setAInt: 5]; NSLog(@"Valor eh: %i", [m aInt]); [m setNome: @"Alex"]; NSLog(@"Nome eh: %s", [[m nome] UTF8String]); [m release]; [pool drain]; return 0; }
você deve ter notado, que nas chamadas eu utilizei “setAInt” e “setNome” para setar os valores e “aInt” e “nome” para recuperar os valores, o “@synthesize” criou esses métodos na hora da compilação, mas se você utiliza o XCode, ficará surpreso em saber que ele oferece no auto-complete esses métodos.
após compilar e rodar a saída que obtive foi essa:
[code]
2010-04-28 23:24:13.552 acessor[1217:a0f] Valor eh: 5
2010-04-28 23:24:13.554 acessor[1217:a0f] Nome eh: Alex
[/code]
Até o próximo artigo.