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:
[code lang=”c”]
– (void) setNome: (NSString *) _nome
{
[nome release];
nome = [[NSString alloc] initWithString: _nome];
}
– (NSString *) nome
{
return nome;
}
[/code]
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”:
[code lang=”c”]
#import <Foundation/Foundation.h>
@interface MyClass1 : NSObject
{
int aInt;
NSString *nome;
}
@property int aInt;
@property (copy, nonatomic) NSString *nome;
@end
[/code]
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”:
[code lang=”c”]
#import “MyClass1.h”
@implementation MyClass1
@synthesize aInt;
@synthesize nome;
@end
[/code]
não está faltando código, é só isso mesmo.
e finalmente um programa que faz a chamada:
[code lang=”c”]
#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;
}
[/code]
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.