02 Fev, 2012 13:18

Blocos de código em Objective-C

Introdução

Para contextualizar, veja os dois exemplos de utilização de bloco de código. No primeiro exemplo, vamos chamar o método do animateWithDuration:animations: da classe UIView:

CGRect novoFrame = CGRectMake(176.0, 258.0, 72.0, 96.0);
[UIView animateWithDuration:2.0
     animations:^ {
          self.view.alpha = 1.0;
          self.view.frame = novoFrame;
          self.view.transform = CGAffineTransformMakeRotation(M_PI);
     }
];

Nesse caso, quando a animação for chamada, três transformações serão efetuadas: o alpha, o frame e a rotação de 180 graus na view. Perceba que não há nenhum parâmetro sendo passado para o bloco, e que é possível utilizar variáveis criadas fora do bloco, desde que o escopo permita isso. Além disso, é possível utilizar propriedades da instância da classe onde está o código.

Já no segundo, vamos chamar o método enumerateObjectsUsingBlock: da classe NSArray:

NSArray *nomes = 
     [NSArray arrayWithObjects:
            @"Afonso", @"Felipe", 
            @"Hildi", @"Karin", 
            @"Quintana" nil];

[nomes enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
     NSLog(@"%@ nome na posição %d", object, index);
}];

Já explico melhor como esse bloco funciona. Por hora, perceba que ele recebe três parâmetros. Olhando a documentação, sabemos que o bloco de código é executado para cada um dos elementos do NSArray. O primeiro parâmetro, object, é um dos elementos da coleção. A segunda variável (index) armazena o índice de object no array. E o terceiro parâmetro (um ponteiro para uma variável boolean) serve para ser utilizado dentro do bloco caso você queira parar a enumeração dos itens.

Uma vez explicado (bem por alto, reconheço) o modo como utilizar os blocos, vamos mostrar como funciona a sintaxe deles.

Sintaxe básica

Como explicado anteriormente, um bloco é simplesmente um conjunto de código executável. Neste exemplo mais simples,

^ {
     NSDate *data = [NSDate date];
     NSLog(@"A data e a hora agora é %@", data);
};

o acento circunflexo inicia o bloco, enquanto as chaves delimitam o corpo do bloco. Nesse caso, temos um bloco se comportando como um método anônimo.

Mas, sendo anônimo, como utilizar esse bloco? A maneira mais comum é a do primeiro exemplo (animação da view), em que eu passo o bloco como parâmetro, que, obviamente, é um bloco anônimo. Outra maneira de utilizar o bloco é associá-lo a uma variável e então chamar a variável. Veja como ficaria o código anterior:

void (^agora)(void) = ^ {
     NSDate *data = [NSDate date];
     NSLog(@"A data e a hora agora é %@", data);
};

Agora sim a sintaxe ficou um pouco mais complexa. Veja a imagem abaixo para entender como o bloco deve ser declarado:

Como você pode perceber, o nome do bloco é sempre declarado entre parêntesis. No nosso exemplo, a variável agora pode ser atribuída a blocos que não tenham retorno (o primeiro void) e que não tenham parâmetro (o segundo void). Para executar o código dentro do bloco, basta chamar:

agora();

Olhando o exemplo da animação da UIView, caso eu quiséssemos passar o bloco agora para o método bastaria fazer:

[UIView animateWithDuration:2.0 animations:agora];

Parâmetros para o bloco

Como toda função que se preze, um bloco pode receber parâmetros. Imagine um bloco que, dado um inteiro, retorna esse número ao quadrado. Declarando um bloco anônimo, temos o seguinte:

^(int numero) {
     return numero * numero;
};

agora, associando a uma variável, temos:

int (^quadrado)(int) = ^(int numero) {
     return numero * numero;
};

e fazendo a associação anterior:

Para utilizar a variável, nada mais simples:

int q = quadrado(8); //q tem valor 64

Nesse caso, só há um parâmetro inteiro. Para outros parâmetros, basta separar os tipos deles por vírgula. Um bloco de método que multiplica duas variáveis ficaria assim:

int (^multiplicar)(int, int) = ^(int a, int b) {
    return a * b;
};

E, obviamente, a variável pode ser chamada da seguinte forma:

int x = multiplicar(2,3); //x tem valor 6

Enfim, espero que essa breve (nem tão breve assim) introdução sobre blocos tenha ajudado. Para um maior aprofundamento, vale a pena dar uma lida na documentação da Apple sobre o assunto. Qualquer dúvida, manda aí nos comentários.

Ao navegar neste site, você consente o uso de cookies nossos e de terceiros, que coletam informações anônimas e são essenciais para melhorar sua experiência em nosso site.