Introdução ao Objective-C – Synthesized Accessor

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.