Continuando meus estudos com Objective-C, existem algumas funcionalidades que me deixam realmente surpreso. Duas delas são Categorias e Blocos.

Para facilitar, vamos ver um código Ruby para dar um exemplo do que quero fazer:

1
2
3
4
5
6
7
class Array
  def each_element
    for elem in self
      yield(elem)
    end
  end
end

Sabemos que em Ruby, todas as classes podem ser abertas e extendidas, incluindo classes padrão da linguagem como Array ou String. Isso permite extender a própria linguagem e é o que o pacote ActiveSupport do Rails faz, ao adicionar métodos como #days à classe Fixnum, permitindo operações como 2.days – 1.day, por exemplo.

Em linguagens como Java isso não é possível porque as classes são fechadas, e inclusive muitas delas são finals o que impedem criar sub-classes a partir delas. Por exemplo, não se pode criar uma classe herdando de String. Isso acaba dando origem a muitas classes acessórias como StringUtils, o que eu acho particularmente não elegante.

No exemplo acima, reabri a classe padrão Array do Ruby e fiz minha própria versão do método each, que já existe, chamando-o de each_element somente com objetivos didáticos para este artigo. Agora podemos pegar um array normal e chamar esse método nele:

1
2
3
4
list = ["a", "b", "c"]
list.each_element do |elem|
  puts elem
end

Mais do que extender classes, o Ruby possui outra funcionalidade muito flexível chamada blocos ou closures/fechamentos (eu já escrevi sobre blocos e closures antes pra RubyLearning. Sugiro ler para entender o conceito)

Essas são duas funcionalidades que muitos poderiam imaginar que só seriam possíveis em linguagens altamente dinâmicas como Ruby, Python ou Smalltalk. Já Objective-C é uma extensão da linguagem C, algo considerado por muitos como tão baixo nível que nem se imaginariam ser possível. Será?

Ultimamente ando brincando de desenvolvimento iPhone e pra isso caí no Objective-C. Gosto muito da linguagem. Já conhecia um pouco do básico dele mas foi a primeira vez que comecei a codificar de verdade. Alguns podem não gostar da sintaxe ou de algumas das ferramentas (realmente o XCode não é completo nem robusto o suficiente, mas dá pro gasto). Mas no geral acho o fluxo de desenvolvimento bastante agradável.

Logo de cara uma coisa que confunde os que sempre trabalharam com plataformas com Garbage Collector é o gerenciamento manual de memória. Vou me abster da discussão sobre se é melhor ou pior e os trade-offs. Na prática, é simples manter isso manualmente.

Uma coisa que confunde no início é o NSAutoreleasePool. Todo projeto Cocoa começa com algo parecido com isto, no main.m:

1
2
3
4
5
6
int main(int argc, char *argv[]) {   
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}