- (void) insertObject:(id) objeto atIndex:(NSInteger) indice;
A declaração do método começa com o tipo de acesso, seguido do tipo de retorno
e do nome do método. Se o método começa com o sinal de soma ( +) significa que ele
é um método de classe (que é algo próximo ao static do Java e C#), e se começar
com o sinal de subtração ( -), é um método de instância. Veremos mais sobre isso
no capítulo sobre Objective-C avançado. O retorno pode ser qualquer tipo válido de
Objective-C ou C, como int, float, id, NSInteger, void etc.
Para passar um argumento para o método é bastante simples, bastando utilizar o
sinal de dois pontos (:) para separar o nome do método da variável. Por exemplo,
o código abaixo insere uma empresa em uma posição específica:
[catalogo insertObject:empresa atIndex:3];
44
Casa do Código
Capítulo 3. Mais Objective-C e Xcode
Toda invocação de método precisa ser feita entre colchetes, aninhando-os con-
forme necessário (ou seja, colchete dentro de colchete dentro de colchete). Sim, o
código fica um pouco difícil de ler, em especial enquanto você está aprendendo mais
da linguagem.
Já um método que recebe múltiplos argumentos pode assustar um pouco mais
(pelo menos assustou a mim, por semanas), porém compreender sua estrutura é
fundamental. Considere o seguinte método, também de NSMutableArray, que
serve para substituir uma parte dos elementos com objetos de outro NSArray:
- (void)replaceObjectsInRange:(NSRange) range
withObjectsFromArray:(NSArray *) outroArray
range:(NSRange) rangeDoOutroArray
Para efeitos de comparação, o mesmo método em Java seria declarado parecido
com isso::
void replaceObjectsInRange(NSRange range, NSArray outroArray,
NSRange rangeDoOutroArray);
Para visualizar melhor a formação da assinatura do método, veja a figura 3.11
Figura 3.11: Estrutura da assinatura de um método em Objective-C
Note que, embora assustador em um primeiro momento, o padrão de construção
para os demais argumentos se repete, sendo formado sempre por 3 partes: a palavra
que fará parte do nome do método, o tipo da variável e o nome da variável em si.
45
3.16. Criando instâncias de objetos
Casa do Código
É esta última que será utilizada dentro do método. Muitas vezes, a palavra que faz
parte do nome do método e a variável costumam ser iguais, mas isso não é uma regra.
A nomenclatura irá variar de acordo com cada caso, sendo que o mais importante
é que você utilize nomes que façam sentido ao contexto de uso. Considere o exemplo
abaixo, de um método que recebe o nome e quantidade de funcionários de uma
empresa, e retorna uma instância da classe:
-(Empresa *) criaEmpresaComNome:(NSString *) nome
comNumeroDeFuncionarios:(int) quantidade {
Empresa *e = [[Empresa alloc] init];
e.nome = nome;
e.quantidadeFuncionarios = quantidade;
return e;
}
Para invocar, fazemos:
Empresa *novaEmpresa = [self criaEmpresaComNome:@"Jujubas LTDA"
comNumeroDeFuncionarios:3];
A verbosidade do nome dos métodos tem um motivo especial, que é fazer com
que o código seja fácil de ler e expresse bem o domínio no qual é aplicado.
3.16
Criando instâncias de objetos
Para poder criar instâncias de classes em Objective-C são necessários dois passos:
alocar memória, e iniciar o objeto. Estes passos geralmente são feitos em conjunto, e
o objeto somente poderá ser utilizado depois que estes dois passos tiverem sido com-
pletados com sucesso. Também não existe o conceito de construtores
propriamente
ditos, mas sim de inicializadores, que por padrão chama-se init. Veja o código
abaixo:
Empresa *e = [[Empresa alloc] init];
A primeira parte do processo de instanciação ocorre com o método alloc,
o qual reserva memória necessária para todas as variáveis de instância e as inicia
com os valores padrão. Em seguida, o método init prepara a instância de fato,
permitindo que seja utilizada. O método init retorna um tipo id, que é como
um ponteiro para qualquer objeto"; pense nele como sendo um primo do Object
46
Casa do Código
Capítulo 3. Mais Objective-C e Xcode
de Java e C#, contudo muito mais abrangente (existe o tipo NSObject, porém).
init é disponibilizado por padrão, não sendo necessário que você implemente-o
toda vez. Entretanto, caso queira fazer uma rotina de inicialização do objeto, basta
sobrescrevê-lo:
1 -(id) init {
2
self = [super init];
3
4
if (self) {
5
// Se chegou aqui, a inicialização ocorreu com sucesso
6
}
7
8
return self;
9 }
A linha 2 invoca o método init na classe-pai (que será pelo menos NSObject),
enquanto a linha 4 verifica se o processo ocorreu com sucesso. Caso tenha falhado,
self irá conter o valor nil.
É possível criar inicializadores customizados, exatamente como faríamos como
qualquer outro método, prestando atenção apenas na necessidade de chamar algum
outro inicializador da classe-pai (ou um outro na mesma classe, que eventualmente
chame o da classe-pai). Por exemplo, poderíamos criar um inicializador para a classe
Empresa que já recebe o nome e a quantidade de funcionários: