Objetivo-C

Da Wikipédia, a enciclopédia livre
Ir para a navegação Saltar para pesquisar

Objetivo-C
FamíliaC
Projetado porTom Love e Brad Cox
Apareceu pela primeira vez1984 ; 38 anos atrás ( 1984 )
Versão estável
2,0 [1]
Disciplina de digitaçãoestático , dinâmico , fraco
SOMultiplataforma
Extensões de nome de arquivo.h, .m, .mm, .M
Local na rede Internetdesenvolvedor.apple.com
Principais implementações
Clang , GCC
Influenciado por
C , Smalltalk
Influenciado
Groovy , Java , Nu , Objective-J , TOM , Swift [2]

Objective-C é uma linguagem de programação orientada a objetos de propósito geral que adiciona mensagens no estilo Smalltalk à linguagem de programação C. Originalmente desenvolvido por Brad Cox e Tom Love no início dos anos 80, foi selecionado pela NeXT para seu sistema operacional NeXTSTEP . Objective-C era a linguagem de programação padrão suportada pela Apple para desenvolver macOS (que descendeu de NeXTSTEP [3] ) e aplicativos iOS usando suas respectivas interfaces de programação de aplicativos (APIs), Cocoa e Cocoa Touch , até a introdução do Swift em 2014. [4]

Programas em Objective-C desenvolvidos para sistemas operacionais que não são da Apple ou que não são dependentes de APIs da Apple também podem ser compilados para qualquer plataforma suportada por GNU GCC ou LLVM / Clang .

Os arquivos de programa de 'mensagens/implementação' do código-fonte do Objective-C geralmente têm extensões de nome de arquivo .m , enquanto os arquivos de 'cabeçalho/interface' do Objective-C têm extensões .h , o mesmo que os arquivos de cabeçalho C. Os arquivos Objective-C++ são indicados com uma extensão de arquivo .mm .

História

O Objective-C foi criado principalmente por Brad Cox e Tom Love no início dos anos 80 em sua empresa Productivity Products International (PPI) . [5]

Levando à criação de sua empresa, ambos foram apresentados ao Smalltalk enquanto estavam no Centro de Tecnologia de Programação da ITT Corporation em 1981. O primeiro trabalho em Objective-C remonta a essa época. [6] Cox ficou intrigado com os problemas de verdadeira reutilização no projeto e programação de software. Ele percebeu que uma linguagem como Smalltalk seria inestimável na construção de ambientes de desenvolvimento para desenvolvedores de sistemas na ITT. No entanto, ele e Tom Love também reconheceram que a compatibilidade com versões anteriores com C era extremamente importante no meio de engenharia de telecomunicações da ITT. [7]

Cox começou a escrever um pré-processador para C para adicionar algumas das habilidades do Smalltalk. Ele logo teve uma implementação de trabalho de uma extensão orientada a objetos para a linguagem C , que ele chamou de "OOPC" para Object-Oriented Pre-Compiler. [8] Love foi contratado pela Schlumberger Research em 1982 e teve a oportunidade de adquirir a primeira cópia comercial do Smalltalk-80, que influenciou ainda mais o desenvolvimento de sua ideia. A fim de demonstrar que o progresso real poderia ser feito, Cox mostrou que fazer componentes de software intercambiáveisrealmente precisava de apenas algumas mudanças práticas nas ferramentas existentes. Especificamente, eles precisavam oferecer suporte a objetos de maneira flexível, ser fornecidos com um conjunto utilizável de bibliotecas e permitir que o código (e quaisquer recursos necessários ao código) fossem agrupados em um formato multiplataforma.

Love e Cox eventualmente formaram a PPI para comercializar seu produto, que acoplou um compilador Objective-C com bibliotecas de classes. Em 1986, Cox publicou a principal descrição do Objective-C em sua forma original no livro Object-Oriented Programming, An Evolutionary Approach . Embora ele tenha sido cuidadoso em apontar que há mais no problema da reutilização do que apenas o que o Objective-C fornece, a linguagem frequentemente se viu comparada recurso por recurso com outras linguagens.

Popularização através da NeXT

Em 1988, a NeXT licenciou Objective-C da StepStone (o novo nome da PPI, proprietária da marca registrada Objective-C) e estendeu o compilador GCC para suportar Objective-C. A NeXT desenvolveu as bibliotecas AppKit e Foundation Kit nas quais a interface de usuário NeXTSTEP e o Interface Builder foram baseados. Embora as estações de trabalho NeXT não tenham causado grande impacto no mercado, as ferramentas foram amplamente elogiadas no setor. Isso levou a NeXT a abandonar a produção de hardware e se concentrar em ferramentas de software, vendendo NeXTSTEP (e OPENSTEP) como uma plataforma para programação personalizada.

A fim de contornar os termos da GPL , a NeXT originalmente pretendia enviar o frontend Objective-C separadamente, permitindo ao usuário vinculá-lo ao GCC para produzir o executável do compilador. Embora inicialmente aceito por Richard M. Stallman , este plano foi rejeitado depois que Stallman consultou os advogados do GNU e a NeXT concordou em tornar o Objective-C parte do GCC. [9]

O trabalho para estender o GCC foi liderado por Steve Naroff, que se juntou à NeXT vindo da StepStone. As alterações do compilador foram disponibilizadas de acordo com os termos da licença GPL , mas as bibliotecas de tempo de execução não, tornando a contribuição de código aberto inutilizável para o público em geral. Isso levou outras partes a desenvolver tais bibliotecas de tempo de execução sob licença de código aberto. Mais tarde, Steve Naroff também foi o principal colaborador para trabalhar na Apple para construir o frontend Objective-C para Clang .

O projeto GNU começou a trabalhar em sua implementação de software livre do Cocoa , chamado GNUstep , baseado no padrão OpenStep . [10] Dennis Glatting escreveu o primeiro runtime GNU Objective-C em 1992. O runtime GNU Objective-C, que está em uso desde 1993, é aquele desenvolvido por Kresten Krab Thorup quando ele era um estudante universitário na Dinamarca . [ carece de fontes ] Thorup também trabalhou na NeXT de 1993 a 1996. [11]

Desenvolvimento da Apple e Swift

Depois de adquirir a NeXT em 1996, a Apple Computer usou o OpenStep em seu então novo sistema operacional, o Mac OS X. Isso incluiu Objective-C, a ferramenta de desenvolvedor baseada em Objective-C da NeXT, Project Builder , e sua ferramenta de design de interface, Interface Builder . Ambos foram posteriormente mesclados em um aplicativo, o Xcode . A maior parte da API Cocoa atual da Apple é baseada em objetos de interface OpenStep e é o ambiente Objective-C mais significativo sendo usado para desenvolvimento ativo.

Na WWDC 2014, a Apple introduziu uma nova linguagem, Swift , que foi caracterizada como "Objective-C sem o C".

Sintaxe

Objective-C é uma camada fina sobre C e é um " superconjunto estrito " de C, o que significa que é possível compilar qualquer programa C com um compilador Objective-C e incluir livremente o código da linguagem C dentro de uma classe Objective-C. [12] [13] [14] [15] [16] [17]

Objective-C deriva sua sintaxe de objeto de Smalltalk . Toda a sintaxe para operações não orientadas a objetos (incluindo variáveis ​​primitivas, pré-processamento, expressões, declarações de funções e chamadas de funções) são idênticas às de C, enquanto a sintaxe para recursos orientados a objetos é uma implementação de Smalltalk- mensagens de estilo.

Mensagens

O modelo Objective-C de programação orientada a objetos é baseado na passagem de mensagens para instâncias de objetos. Em Objective-C não se chama um método ; um envia uma mensagem . Isso é diferente do modelo de programação no estilo Simula usado pelo C++ . A diferença entre esses dois conceitos está em como o código referenciado pelo método ou nome da mensagem é executado. Em uma linguagem de estilo Simula, o nome do método é, na maioria dos casos , vinculado a uma seção de código na classe de destino pelo compilador. Em Smalltalk e Objective-C, o destino de uma mensagem é resolvido em tempo de execução, com o próprio objeto receptor interpretando a mensagem. Um método é identificado por um seletorou SEL — um identificador exclusivo para cada nome de mensagem, geralmente apenas uma string terminada em NUL representando seu nome — e resolvido para um ponteiro de método C implementando-o: um IMP . [18] Uma consequência disso é que o sistema de troca de mensagens não possui verificação de tipo. O objeto para o qual a mensagem é direcionada – o receptor – não tem garantia de responder a uma mensagem e, se não responder, gera uma exceção. [19]

Enviar o método de mensagem para o objeto apontado pelo ponteiro obj exigiria o seguinte código em C++ :

obj -> método ( argumento );

Em Objective-C, isso é escrito da seguinte forma:

[ método obj : argumento ]; 

A chamada de "método" é traduzida pelo compilador para a família objc_msgSend(id self, SEL op, ...) de funções de tempo de execução. Diferentes implementações lidam com adições modernas como super . [20] Nas famílias GNU esta função é denominada objc_msg_sendv , mas foi preterida em favor de um sistema de pesquisa moderno sob objc_msg_lookup . [21]

Ambos os estilos de programação têm seus pontos fortes e fracos. A programação orientada a objetos no estilo Simula ( C++ ) permite herança múltipla e execução mais rápida usando vinculação em tempo de compilação sempre que possível, mas não suporta vinculação dinâmica por padrão. Também força todos os métodos a terem uma implementação correspondente, a menos que sejam abstratos. A programação no estilo Smalltalk usada em Objective-C permite que as mensagens não sejam implementadas, com o método resolvido para sua implementação em tempo de execução. Por exemplo, uma mensagem pode ser enviada para uma coleção de objetos, aos quais apenas alguns devem responder, sem medo de produzir erros de tempo de execução. A passagem de mensagens também não requer que um objeto seja definido em tempo de compilação. Uma implementação ainda é necessária para que o método seja chamado no objeto derivado. (Consulte a seção de tipagem dinâmica abaixo para obter mais vantagens da vinculação dinâmica (atrasada).)

Interfaces e implementações

O Objective-C requer que a interface e a implementação de uma classe estejam em blocos de código declarados separadamente. Por convenção, os desenvolvedores colocam a interface em um arquivo de cabeçalho e a implementação em um arquivo de código. Os arquivos de cabeçalho, normalmente com o sufixo .h, são semelhantes aos arquivos de cabeçalho C, enquanto os arquivos de implementação (método), normalmente com o sufixo .m, podem ser muito semelhantes aos arquivos de código C.

Interface

Isso é análogo às declarações de classe usadas em outras linguagens orientadas a objetos, como C++ ou Python.

A interface de uma classe geralmente é definida em um arquivo de cabeçalho. Uma convenção comum é nomear o arquivo de cabeçalho após o nome da classe, por exemplo, Ball.h conteria a interface para a classe Ball .

Uma declaração de interface assume a forma:

@interface  classname  : superclassname  {
  //variáveis ​​de instância 
}
+  classMethod1 ;
+  ( tipo_retorno ) classMethod2 ;
+  ( return_type ) classMethod3: ( param1_type ) param1_varName ;

-  ( return_type ) instanceMethod1With1Parameter: ( param1_type ) param1_varName ;
-  ( return_type ) instanceMethod2With2Parameters: ( param1_type ) param1_varName
                              param2_callName: ( param2_type ) param2_varName ;
@fim

Acima, os sinais de mais denotam métodos de classe , ou métodos que podem ser chamados na própria classe (não em uma instância), e os sinais de menos denotam métodos de instância , que só podem ser chamados em uma instância específica da classe. Os métodos de classe também não têm acesso a variáveis ​​de instância .

O código acima é aproximadamente equivalente à seguinte interface C++ :

classe  classname : public superclassname {    
protegido :
  // variáveis ​​de instância

público :
  // Funções de classe (estática) 
static void * classMethod1 ();    
  estático return_type classMethod2 ();  
  static return_type classMethod3 ( param1_type param1_varName );   

  // Funções da instância (membro) 
return_type instanceMethod1With1Parameter ( param1_type param1_varName );    
  tipo_de_retorno
  instanceMethod2With2Parameters ( param1_type param1_varName , 
                                 param2_type param2_varName = default );   
};

Observe que instanceMethod2With2Parameters:param2_callName: demonstra a intercalação de segmentos seletores com expressões de argumento, para as quais não há equivalente direto em C/C++.

Os tipos de retorno podem ser qualquer tipo C padrão , um ponteiro para um objeto genérico Objective-C, um ponteiro para um tipo específico de objeto, como NSArray *, NSImage * ou NSString *, ou um ponteiro para a classe à qual o método pertence (tipo de instância). O tipo de retorno padrão é o id de tipo genérico Objective-C .

Os argumentos de método começam com um nome que rotula o argumento que faz parte do nome do método, seguido por dois pontos seguido pelo tipo de argumento esperado entre parênteses e o nome do argumento. O rótulo pode ser omitido.

-  ( void ) setRangeStart: ( int ) início fim: ( int ) fim ; 
-  ( void ) importDocumentWithName: ( NSString * ) nome 
      withSpecifiedPreferences: ( Preferences * ) prefs 
                    beforePage: ( int ) insertPage ;

Um derivado da definição de interface é a categoria , que permite adicionar métodos a classes existentes. [22]

Implementação

A interface apenas declara a interface de classe e não os métodos em si: o código real é escrito no arquivo de implementação. Arquivos de implementação (método) normalmente têm a extensão de arquivo .m, que originalmente significava "mensagens". [23]

@implementation  classname
+  ( tipo_de_retorno ) classMethod { 
  // implementação 
}
-  ( return_type ) instanceMethod { 
  // implementação 
}
@fim

Os métodos são escritos usando suas declarações de interface. Comparando Objective-C e C:

-  ( int ) método: ( int ) i { 
  return [ self square_root : i ];  
}
função int ( int i ) {   
  return raiz_quadrada ( i ); 
}

A sintaxe permite a pseudonomeação de argumentos .

-  ( void ) changeColorToRed: ( float ) red green: ( float ) green blue: ( float ) blue {   
  //... Implementação... 
}

// Chamado assim: 
[ myColor changeColorToRed : 5.0 green : 2.0 blue : 6.0 ] ;   

As representações internas de um método variam entre diferentes implementações de Objective-C. Se myColor for da classe Color , o método de instância -changeColorToRed:green:blue: pode ser rotulado internamente como _i_Color_changeColorToRed_green_blue . O i é para se referir a um método de instância, com a classe e os nomes dos métodos anexados e os dois pontos alterados para sublinhados. Como a ordem dos parâmetros faz parte do nome do método, ela não pode ser alterada para se adequar ao estilo ou expressão de codificação, como ocorre com os parâmetros nomeados verdadeiros.

No entanto, os nomes internos da função raramente são usados ​​diretamente. Geralmente, as mensagens são convertidas em chamadas de função definidas na biblioteca de tempo de execução Objective-C. Não é necessariamente conhecido no momento do link qual método será chamado porque a classe do receptor (o objeto que está enviando a mensagem) não precisa ser conhecida até o tempo de execução.

Instanciação

Uma vez que uma classe Objective-C é escrita, ela pode ser instanciada. Isso é feito alocando primeiro uma instância não inicializada da classe (um objeto) e depois inicializando-a. Um objeto não está totalmente funcional até que ambas as etapas sejam concluídas. Essas etapas devem ser realizadas com uma linha de código para que nunca haja um objeto alocado que não tenha sido inicializado (e porque não é aconselhável manter o resultado intermediário, pois -initpode retornar um objeto diferente daquele em que é chamado).

Instanciação com o inicializador padrão sem parâmetros:

MeuObjeto * foo = [[ MeuObjeto alloc ] init ];     

Instanciação com um inicializador personalizado:

MyObject * foo = [[ MyObject alloc ] initWithString : myString ];     

No caso em que nenhuma inicialização personalizada está sendo executada, o método "new" geralmente pode ser usado no lugar das mensagens alloc-init:

MeuObjeto * foo = [ MeuObjeto novo ];    

Além disso, algumas classes implementam inicializadores de método de classe. Como +new, eles combinam +alloce -init, mas diferentemente +newde , eles retornam uma instância de liberação automática. Alguns inicializadores de métodos de classe usam parâmetros:

MeuObjeto * foo = [ Objeto MeuObjeto ];    
MyObject * bar = [ MyObject objectWithString : @"Wikipedia :)" ];    

A mensagem alloc aloca memória suficiente para armazenar todas as variáveis ​​de instância de um objeto, define todas as variáveis ​​de instância com valores zero e transforma a memória em uma instância da classe; em nenhum momento durante a inicialização a memória é uma instância da superclasse.

A mensagem init executa a configuração da instância na criação. O método init é frequentemente escrito da seguinte forma:

-  ( id ) init { 
    self = [ super init ];   
    se ( eu ) {  
        // executa a inicialização do objeto aqui 
}    
    retorno próprio ; 
}

No exemplo acima, observe o idtipo de retorno. Esse tipo significa "ponteiro para qualquer objeto" em Objective-C (consulte a seção de tipagem dinâmica ).

O padrão inicializador é usado para garantir que o objeto seja inicializado corretamente por sua superclasse antes que o método init execute sua inicialização. Ele executa as seguintes ações:

  1. self = [super init]
    Envia à instância da superclasse uma mensagem de inicialização e atribui o resultado a self (ponteiro para o objeto atual).
  2. se (eu)
    Verifica se o ponteiro de objeto retornado é válido antes de realizar qualquer inicialização.
  3. retornar a si mesmo
    Retorna o valor de self para o chamador.

Um ponteiro de objeto inválido tem o valor nil ; instruções condicionais como "if" tratam nil como um ponteiro nulo, então o código de inicialização não será executado se [super init] retornar nil. Se houver um erro na inicialização, o método init deve executar qualquer limpeza necessária, incluindo o envio de uma mensagem de "liberação" para self e retornar nil para indicar que a inicialização falhou. Qualquer verificação de tais erros só deve ser realizada após ter chamado a inicialização da superclasse para garantir que a destruição do objeto seja feita corretamente.

Se uma classe tiver mais de um método de inicialização, apenas um deles (o "inicializador designado") precisa seguir esse padrão; outros devem chamar o inicializador designado em vez do inicializador da superclasse.

Protocolos

Em outras linguagens de programação, elas são chamadas de "interfaces".

O Objective-C foi estendido na NeXT para introduzir o conceito de herança múltipla de especificação, mas não de implementação, por meio da introdução de protocolos . Este é um padrão alcançável como uma classe base herdada múltipla abstrata em C++ ou como uma "interface" (como em Java e C# ). O Objective-C faz uso de protocolos ad hoc chamados protocolos informais e protocolos impostos pelo compilador chamados protocolos formais .

Um protocolo informal é uma lista de métodos que uma classe pode optar por implementar. Está especificado na documentação, pois não tem presença no idioma. Os protocolos informais são implementados como uma categoria (veja abaixo) no NSObject e geralmente incluem métodos opcionais que, se implementados, podem alterar o comportamento de uma classe. Por exemplo, uma classe de campo de texto pode ter um delegado que implementa um protocolo informal com um método opcional para realizar o preenchimento automático de texto digitado pelo usuário. O campo de texto descobre se o delegado implementa esse método (via reflection ) e, em caso afirmativo, chama o método do delegado para dar suporte ao recurso de preenchimento automático.

Um protocolo formal é semelhante a uma interface em Java, C# e Ada 2005 . É uma lista de métodos que qualquer classe pode se declarar para implementar. As versões do Objective-C anteriores a 2.0 exigiam que uma classe implementasse todos os métodos em um protocolo que ela declarasse adotar; o compilador emitirá um erro se a classe não implementar todos os métodos de seus protocolos declarados. O Objective-C 2.0 adicionou suporte para marcar certos métodos em um protocolo como opcional, e o compilador não imporá a implementação de métodos opcionais.

Uma classe deve ser declarada para implementar esse protocolo para ser considerada em conformidade com ele. Isso é detectável em tempo de execução. Os protocolos formais não podem fornecer nenhuma implementação; eles simplesmente asseguram aos chamadores que as classes que estão em conformidade com o protocolo fornecerão implementações. Na biblioteca NeXT/Apple, os protocolos são frequentemente usados ​​pelo sistema de Objetos Distribuídos para representar as habilidades de um objeto em execução em um sistema remoto.

A sintaxe

@protocol  NSLocking 
-  ( void ) lock ;
-  ( void ) desbloquear ;
@fim

denota que existe a ideia abstrata de travamento. Ao declarar na definição da classe que o protocolo está implementado,

@interface  NSLock  : NSObject < NSLocking > 
// ... 
@fim

instâncias do NSLock afirmam que fornecerão uma implementação para os dois métodos de instância.

Digitação dinâmica

Objective-C, como Smalltalk, pode usar tipagem dinâmica : um objeto pode receber uma mensagem que não está especificada em sua interface. Isso pode permitir maior flexibilidade, pois permite que um objeto "capture" uma mensagem e envie a mensagem para um objeto diferente que possa responder à mensagem adequadamente ou, da mesma forma, enviar a mensagem para outro objeto. Esse comportamento é conhecido como encaminhamento ou delegação de mensagens (veja abaixo). Alternativamente, um manipulador de erros pode ser usado caso a mensagem não possa ser encaminhada. Se um objeto não encaminhar uma mensagem, responder a ela ou manipular um erro, o sistema gerará uma exceção de tempo de execução. [24] Se as mensagens forem enviadas para nil(o ponteiro de objeto nulo), eles serão ignorados silenciosamente ou gerarão uma exceção genérica, dependendo das opções do compilador.

As informações de tipagem estática também podem ser adicionadas opcionalmente às variáveis. Esta informação é então verificada em tempo de compilação. Nas quatro instruções a seguir, são fornecidas informações de tipo cada vez mais específicas. As instruções são equivalentes em tempo de execução, mas as informações extras permitem que o compilador avise o programador se o argumento passado não corresponder ao tipo especificado.

-  ( void ) setMeuValor: ( id ) foo ;

Na declaração acima, foo pode ser de qualquer classe.

-  ( void ) setMyValue: ( id < NSCopying > ) foo ;

Na declaração acima, foo pode ser uma instância de qualquer classe que esteja em conformidade com o NSCopyingprotocolo.

-  ( void ) setMyValue: ( NSNumber * ) foo ; 

Na instrução acima, foo deve ser uma instância da classe NSNumber .

-  ( void ) setMyValue: ( NSNumber < NSCopying > * ) foo ; 

Na instrução acima, foo deve ser uma instância da classe NSNumber e deve estar em conformidade com o NSCopyingprotocolo.

Em Objective-C, todos os objetos são representados como ponteiros e a inicialização estática não é permitida. O objeto mais simples é o tipo para o qual id ( objc_obj * ) aponta, que possui apenas um ponteiro isa descrevendo sua classe. Outros tipos de C, como valores e estruturas, permanecem inalterados porque não fazem parte do sistema de objetos. Essa decisão difere do modelo de objeto C++, onde structs e classes são unidas.

Encaminhando

Objective-C permite o envio de uma mensagem para um objeto que pode não responder. Em vez de responder ou simplesmente descartar a mensagem, um objeto pode encaminhar a mensagem para um objeto que pode responder. O encaminhamento pode ser usado para simplificar a implementação de determinados padrões de design , como o padrão observador ou o padrão proxy .

O runtime Objective-C especifica um par de métodos em Object

  • métodos de encaminhamento:
    -  ( retval_t ) forward: ( SEL ) sel args: ( arglist_t ) args ; // com GCC - ( id ) para frente: ( SEL ) sel args: ( marg_list ) args ; // com sistemas NeXT/Apple  
       
    
  • métodos de ação:
    -  ( retval_t ) performv: ( SEL ) sel args: ( arglist_t ) args ; // com GCC - ( id ) performv: ( SEL ) sel args: ( marg_list ) args ; // com sistemas NeXT/Apple  
       
    

Um objeto que deseja implementar o encaminhamento precisa apenas substituir o método de encaminhamento por um novo método para definir o comportamento do encaminhamento. O método de ação performv:: não precisa ser substituído, pois esse método apenas executa uma ação com base no seletor e nos argumentos. Observe o tipo, que é o tipo de mensagens em Objective-C. SEL

Nota: em OpenStep, Cocoa e GNUstep, os frameworks mais usados ​​de Objective-C, não se usa a classe Object . O método - (void)forwardInvocation:(NSInvocation *)anInvocation da classe NSObject é usado para fazer o encaminhamento.

Exemplo

Aqui está um exemplo de um programa que demonstra os fundamentos do encaminhamento.

Remetente.h
#import <objc/Object.h>

@interface  Encaminhador  : Objeto  {
  destinatário de identificação ; // O objeto para o qual queremos encaminhar a mensagem. }  


// Métodos de acesso. 
-  ( id ) destinatário ;
-  ( id ) setRecipient: ( id ) _recipient ;
@fim
Remetente.m
#import "Forwarder.h"

@implementation  Encaminhador
-  ( retval_t ) forward: ( SEL ) sel args: ( arglist_t ) args {  
  /* 
  * Verifica se o destinatário realmente responde à mensagem. 
  * Isso pode ou não ser desejável, por exemplo, se um destinatário 
  * por sua vez não responder à mensagem, ele mesmo pode encaminhar 
  *. 
  */
  if ([ destinatário respondeToSelector : sel ]) {   
    return [ destinatário performv : sel args : args ];   
  } senão {  
    return [ self error : "O destinatário não responde" ];  
  }
}

-  ( id ) setRecipient: ( id ) _recipient { 
  [ liberação automática do destinatário ]; 
  destinatário = [ _recipient reter ];   
  retorno próprio ; 
}

-  ( id ) destinatário { 
  destinatário de retorno ; 
}
@fim
Destinatário.h
#import <objc/Object.h>

// Um ​​objeto Destinatário simples. 
@interface  Destinatário  : Objeto
-  ( id ) olá ;
@fim
Destinatário.m
#import "Destinatário.h"

 Destinatário @implementation

-  ( id ) olá { 
  printf ( "O destinatário diz olá! \n " );

  retorno próprio ; 
}

@fim
main.m
#import "Forwarder.h" 
#import "Recipient.h"

int main ( void ) {  
  Reencaminhador * reencaminhador = [ Reencaminhador novo ];    
  Destinatário * destinatário = [ Destinatário novo ];    

  [ forwarder setRecipient : destinatário ]; // Define o destinatário. /*   * Observar o encaminhador não responde a uma mensagem de saudação! Será   * encaminhado. Todos os métodos não reconhecidos serão encaminhados para   *o destinatário   * (se o destinatário responder a eles, conforme escrito no Encaminhador)   */  
  





  [ remetente Olá ]; 

  [ liberação do destinatário ]; 
  [ liberação do remetente ]; 

  retorna 0 ; 
}

Notas

Quando compilado usando gcc , o compilador relata:

$ gcc -x objetivo-c -Wno-import Forwarder.m Recipient.m main.m -lobjc
main.m: Na função `main':
main.m:12: aviso: 'Forwarder' não responde a 'hello'
$

O compilador está relatando o ponto feito anteriormente, que o encaminhador não responde às mensagens de saudação. Nessa circunstância, é seguro ignorar o aviso, pois o encaminhamento foi implementado. A execução do programa produz esta saída:

$ ./a.out
O destinatário diz olá!

Categorias

Durante o projeto do Objective-C, uma das principais preocupações era a manutenção de grandes bases de código. A experiência do mundo da programação estruturada mostrou que uma das principais maneiras de melhorar o código era dividi-lo em partes menores. O Objective-C emprestou e estendeu o conceito de categorias das implementações do Smalltalk para ajudar nesse processo. [25]

Além disso, os métodos dentro de uma categoria são adicionados a uma classe em tempo de execução . Assim, as categorias permitem que o programador adicione métodos a uma classe existente - uma classe aberta - sem a necessidade de recompilar essa classe ou mesmo ter acesso ao seu código-fonte. Por exemplo, se um sistema não contiver um corretor ortográfico em sua implementação String, ele poderá ser adicionado sem modificar o código-fonte String.

Os métodos dentro das categorias tornam-se indistinguíveis dos métodos de uma classe quando o programa é executado. Uma categoria tem acesso total a todas as variáveis ​​de instância dentro da classe, incluindo variáveis ​​privadas.

Se uma categoria declara um método com a mesma assinatura de método de um método existente em uma classe, o método da categoria é adotado. Assim, as categorias podem não apenas adicionar métodos a uma classe, mas também substituir métodos existentes. Esse recurso pode ser usado para corrigir bugs em outras classes reescrevendo seus métodos ou para causar uma mudança global no comportamento de uma classe dentro de um programa. Se duas categorias possuem métodos com o mesmo nome, mas com assinaturas de métodos diferentes, fica indefinido qual método da categoria é adotado.

Outros idiomas tentaram adicionar esse recurso de várias maneiras. O TOM levou o sistema Objective-C um passo adiante e permitiu a adição de variáveis ​​também. Outras linguagens usaram soluções baseadas em protótipos , sendo a mais notável o Self .

As linguagens C# e Visual Basic.NET implementam funcionalidades superficialmente semelhantes na forma de métodos de extensão , mas estes não têm acesso às variáveis ​​privadas da classe. [26] Ruby e várias outras linguagens de programação dinâmicas referem-se à técnica como " macaco patching ".

O Logtalk implementa um conceito de categorias (como entidades de primeira classe) que inclui a funcionalidade de categorias Objective-C (as categorias do Logtalk também podem ser usadas como unidades de composição refinadas ao definir, por exemplo, novas classes ou protótipos; em particular, uma categoria do Logtalk pode ser virtualmente importado por qualquer número de classes e protótipos).

Exemplo de uso de categorias

Este exemplo cria uma classe Integer , definindo primeiro uma classe básica com apenas métodos de acesso implementados e adicionando duas categorias, Arithmetic e Display , que estendem a classe básica. Embora as categorias possam acessar os membros de dados privados da classe base, geralmente é uma boa prática acessar esses membros de dados privados por meio dos métodos de acesso, o que ajuda a manter as categorias mais independentes da classe base. A implementação de tais acessadores é um uso típico de categorias. Outra é usar categorias para adicionar métodos à classe base. No entanto, não é considerado uma boa prática usar categorias para substituição de subclasse, também conhecido como patch de macaco. Os protocolos informais são implementados como uma categoria na classe base NSObject . Por convenção, os arquivos contendo categorias que estendem as classes base terão o nome BaseClass+ExtensionClass.h .

Inteiro.h
#import <objc/Object.h>

@interface  Inteiro  : Objeto  {
  inteiro inteiro ; 
}

-  ( int ) inteiro ;
-  ( id ) inteiro: ( int ) _integer ;
@fim
Inteiro.m
#import "Inteiro.h"

@implementation  Inteiro
-  ( int )  inteiro { 
  retorna inteiro ; 
}

-  ( id )  inteiro: ( int ) _integer {   
  inteiro = _inteiro ;  
  retorno próprio ; 
}
@fim
Inteiro+Aritmético.h
#import "Inteiro.h"

@interface  Inteiro  (aritmética)
-  ( id )  add: ( Integer * ) addend ;   
-  ( id )  sub: ( Integer * ) subtraendo ;   
@fim
Inteiro+Aritmético.m
# import "Inteiro+Aritmético.h"

@implementation  Inteiro  (aritmético)
-  ( id )  add: ( Integer * ) addend {    
  return [ self integer : [ self integer ] + [ addend integer ]];       
}

-  ( id )  sub: ( inteiro * ) subtraendo {    
  return [ self inteiro : [ self inteiro ] - [ subtraendo inteiro ]];       
}
@fim
Integer+Display.h
#import "Inteiro.h"

@interface  Inteiro  (Exibir)
-  ( id )  estrelas do show ;
-  ( id )  showint ;
@fim
Inteiro+Display.m
# import "Integer+Display.h"

@implementation  Inteiro  (Exibir)
-  ( id )  estrelas de exibição { 
  int i , x = [ inteiro próprio ];     
  for ( i = 0 ; i < x ; i ++ ) {        
    printf ( "*" );
  }
  printf ( " \n " );

  retorno próprio ; 
}

-  ( id )  showint { 
  printf ( "%d \n " , [ auto inteiro ]);  

  retorno próprio ; 
}
@fim
main.m
#import "Integer.h" 
#import "Integer+Arithmetic.h" 
#import "Integer+Display.h"

int main ( void ) {  
  Inteiro * num1 = [ Inteiro novo ], * num2 = [ Inteiro novo ];        
  intx ; _ 

  printf ( "Digite um inteiro: " );
  scanf ( "%d" , & x ); 

  [ num1 inteiro : x ]; 
  [ núm1 showstars ]; 

  printf ( "Digite um inteiro: " );
  scanf ( "%d" , & x ); 

  [ num2 inteiro : x ]; 
  [ núm2 estrelas de exibição ]; 

  [ num1 adicionar : num2 ]; 
  [ num1 showint ]; 

  retorna 0 ; 
}

Notas

A compilação é realizada, por exemplo, por:

gcc -x objetivo-c main.m Inteiro.m Inteiro+Aritmética.m Inteiro+Display.m -lobjc

Pode-se experimentar deixando de fora as linhas #import "Integer+Arithmetic.h" e [num1 add:num2] e omitindo Integer+Arithmetic.m na compilação. O programa ainda será executado. Isso significa que é possível misturar e combinar categorias adicionadas, se necessário; se uma categoria não precisa ter alguma habilidade, ela simplesmente não pode ser compilada.

Posando

O Objective-C permite que uma classe substitua totalmente outra classe dentro de um programa. A classe de substituição é dita "posar como" a classe de destino.

A colocação de classe foi declarada obsoleta com o Mac OS X v10.5 e não está disponível no tempo de execução de 64 bits. Funcionalidade semelhante pode ser obtida usando o método swizzling em categorias, que troca a implementação de um método por outro que tenha a mesma assinatura.

Para as versões que ainda suportam posing, todas as mensagens enviadas para a classe de destino são recebidas pela classe posing. Existem várias restrições:

  • Uma classe só pode se apresentar como uma de suas superclasses diretas ou indiretas.
  • A classe posing não deve definir nenhuma nova variável de instância que esteja ausente da classe de destino (embora possa definir ou substituir métodos).
  • A classe alvo pode não ter recebido nenhuma mensagem antes da pose.

Posing, da mesma forma com categorias, permite o aumento global de classes existentes. Posar permite duas características ausentes das categorias:

  • Uma classe posing pode chamar métodos sobrescritos por meio de super, incorporando assim a implementação da classe alvo.
  • Uma classe de pose pode substituir métodos definidos em categorias.

Por exemplo,

@interface  CustomNSApplication  : NSApplication
@fim

@implementation  CustomNSAaplicativo
-  ( void )  setMainMenu: ( NSMenu * ) menu {   
  // faça algo com o menu 
}
@fim

class_poseAs ([ classe CustomNSApplication ], [ classe NSApplication ]);    

Isso intercepta cada chamada de setMainMenu para NSApplication.

#importar

Na linguagem C, a #includediretiva de pré-compilação sempre faz com que o conteúdo de um arquivo seja inserido na fonte nesse ponto. Objective-C tem a #importdiretiva, equivalente, exceto que cada arquivo é incluído apenas uma vez por unidade de compilação, eliminando a necessidade de incluir guardas .

Compilação Linux gcc

// ARQUIVO: hello.m 
#import <Foundation/Foundation.h> 
int main ( int argc , const char * argv [])       
{
    /* meu primeiro programa em Objective-C */
    NSLog ( @"Olá, Mundo! \n " );
    retorna 0 ; 
}
# Linha de comando de compilação para gcc e compilador MinGW: 
$ gcc \ 
    $( gnustep-config --objc-flags )  \ 
    -o hello \ 
    hello.m \ 
    -L /GNUstep/System/Library/Libraries \ 
    -lobjc \
    -lgnusep-base

$ ./olá

Outros recursos

Os recursos do Objective-C geralmente permitem soluções flexíveis e muitas vezes fáceis para problemas de programação.

  • A delegação de métodos a outros objetos e a invocação remota podem ser facilmente implementadas usando categorias e encaminhamento de mensagens.
  • O movimento do ponteiro isa permite que as classes mudem em tempo de execução. Normalmente usado para depuração onde os objetos liberados são transformados em objetos zumbis cujo único propósito é relatar um erro quando alguém os chama. Swizzling também foi usado no Enterprise Objects Framework para criar falhas de banco de dados. [ citação necessária ] Swizzling é usado hoje pelo Foundation Framework da Apple para implementar Key-Value Observando .

Variantes de idioma

Objective-C++

Objective-C++ é uma variante de linguagem aceita pelo front-end da GNU Compiler Collection e Clang , que pode compilar arquivos de origem que usam uma combinação de sintaxe C++ e Objective-C. O Objective-C++ adiciona ao C++ as extensões que o Objective-C adiciona ao C. Como nada é feito para unificar a semântica por trás dos vários recursos da linguagem, certas restrições se aplicam:

  • Uma classe C++ não pode derivar de uma classe Objective-C e vice-versa.
  • Os namespaces C++ não podem ser declarados dentro de uma declaração Objective-C.
  • Declarações Objective-C podem aparecer apenas no escopo global, não dentro de um namespace C++
  • Classes Objective-C não podem ter variáveis ​​de instância de classes C++ que não possuem um construtor padrão ou que possuem um ou mais métodos virtuais , mas ponteiros para objetos C++ podem ser usados ​​como variáveis ​​de instância sem restrição (aloque-os com new no - método de inicialização).
  • A semântica "por valor" de C++ não pode ser aplicada a objetos Objective-C, que são acessíveis apenas por meio de ponteiros.
  • Uma declaração Objective-C não pode estar dentro de uma declaração de modelo C++ e vice-versa. No entanto, os tipos Objective-C (por exemplo, Classname *) podem ser usados ​​como parâmetros de modelo C++.
  • O tratamento de exceções de Objective-C e C++ é distinto; os manipuladores de cada um não podem manipular exceções do outro tipo. Como resultado, os destruidores de objetos não são executados. Isso é mitigado em tempos de execução "Objective-C 2.0" recentes, pois as exceções do Objective-C são substituídas por exceções C++ completamente (tempo de execução da Apple) ou parcialmente quando a biblioteca Objective-C++ está vinculada (GNUstep libobjc2). [27]
  • Blocos Objective-C e lambdas C++11 são entidades distintas. No entanto, um bloco é gerado de forma transparente no macOS ao passar um lambda onde um bloco é esperado. [28]

Objective-C 2.0

Na Worldwide Developers Conference de 2006 , a Apple anunciou o lançamento do "Objective-C 2.0", uma revisão da linguagem Objective-C para incluir "coleção de lixo moderna, aprimoramentos de sintaxe, [29] melhorias de desempenho de tempo de execução, [30] e 64- suporte de bits". O Mac OS X v10.5 , lançado em outubro de 2007, incluía um compilador Objective-C 2.0. O GCC 4.6 suporta muitos novos recursos de Objective-C, como propriedades declaradas e sintetizadas, sintaxe de ponto, enumeração rápida, métodos de protocolo opcionais, atributos de método/protocolo/classe, extensões de classe e uma nova API de tempo de execução GNU Objective-C. [31]

A nomenclatura Objective-C 2.0 representa uma quebra no sistema de versionamento da linguagem, já que a última versão de Objective-C para NeXT foi "objc4". [32] Este nome de projeto foi mantido na última versão do código-fonte de tempo de execução Objective-C legado no Mac OS X Leopard (10.5). [33]

Coleta de lixo

O Objective-C 2.0 forneceu um coletor de lixo geracional conservador opcional . Quando executado em modo compatível com versões anteriores , o tempo de execução transformou operações de contagem de referência como "retain" e "release" em no-ops . Todos os objetos estavam sujeitos à coleta de lixo quando a coleta de lixo estava habilitada. Ponteiros C regulares podem ser qualificados com "__strong" para também acionar as interceptações do compilador da barreira de gravação subjacente e, assim, participar da coleta de lixo. [34] Um subsistema fraco de zeragem também foi fornecido de tal forma que os ponteiros marcados como "__weak" são definidos como zero quando o objeto (ou mais simplesmente, a memória GC) é coletado. O coletor de lixo não existe na implementação iOS do Objective-C 2.[35] A coleta de lixo no Objective-C é executada em um thread em segundo plano de baixa prioridade e pode ser interrompida em eventos do usuário, com a intenção de manter a experiência do usuário responsiva. [36]

A coleta de lixo foi preterida no Mac OS X v10.8 em favor da Contagem Automática de Referência (ARC). [37] Objective-C no iOS 7 rodando em ARM64 usa 19 bits de uma palavra de 64 bits para armazenar a contagem de referência, como uma forma de ponteiros marcados . [38] [39]

Propriedades

O Objective-C 2.0 introduz uma nova sintaxe para declarar variáveis ​​de instância como propriedades , com atributos opcionais para configurar a geração de métodos acessadores. As propriedades são, em certo sentido, variáveis ​​de instância públicas; ou seja, declarar uma variável de instância como uma propriedade fornece a classes externas acesso (possivelmente limitado, por exemplo, somente leitura) a essa propriedade. Uma propriedade pode ser declarada como "somente leitura" e pode ser fornecida com semântica de armazenamento como assign, copyou retain. Por padrão, as propriedades são consideradas atomic, o que resulta em um bloqueio impedindo que vários encadeamentos os acessem ao mesmo tempo. Uma propriedade pode ser declarada como nonatomic, o que remove esse bloqueio.

@interface  Pessoa  : NSObject  {
@público
  NSString * nome ; 
@privado
  int idade ; 
}

@property ( copiar ) NSString * nome ;  
@property ( somente leitura ) int idade ;  

-  ( id ) initWithAge: ( int ) idade ;
@fim

As propriedades são implementadas por meio da palavra- @synthesizechave, que gera métodos getter (e setter, se não somente leitura) de acordo com a declaração da propriedade. Alternativamente, os métodos getter e setter devem ser implementados explicitamente, ou a palavra- @dynamicchave pode ser usada para indicar que os métodos acessadores serão fornecidos por outros meios. Quando compilado usando clang 3.1 ou superior, todas as propriedades que não são explicitamente declaradas com @dynamic, marcadas readonlyou têm getter e setter completos implementados pelo usuário serão automaticamente @synthesize'd' implicitamente.

@implementation  Pessoa
@synthesize nome ; 

-  ( id ) initWithAge: ( int ) initAge { 
  self = [ super init ];   
  se ( eu ) {  
    // NOTA: atribuição direta de variável de instância, não setter de propriedade 
age = initAge ;      
  }
  retorno próprio ; 
}

-  ( int ) idade { 
  idade de retorno ; 
}
@fim

As propriedades podem ser acessadas usando a sintaxe tradicional de passagem de mensagens, notação de ponto ou, na codificação de valor-chave, por nome por meio dos métodos "valueForKey:"/"setValue:forKey:".

Pessoa * aPerson = [[ Person alloc ] initWithAge : 53 ];     
aPessoa . nome = @"Steve" ; // NOTA: notação de ponto, usa setter sintetizado, // equivalente a [aPerson setName: @"Steve"]; NSLog ( @"Acesso por mensagem (%@), notação de ponto(%@), nome da propriedade(% @) e "   
                         

       "acesso direto à variável de instância (% @) " ,
              [ aNome da pessoa ] , 
      aPessoa . name , [ aPerson valueForKey : @"name" ], aPerson -> name );     

Para usar a notação de ponto para invocar acessadores de propriedade em um método de instância, a palavra-chave "self" deve ser usada:

-  ( void ) introduzMyselfWithProperties: ( BOOL ) useGetter { 
  NSLog ( @"Oi, meu nome é %@." , ( useGetter ? self . name : name ));     
  // NOTA: acesso getter vs. ivar 
}

As propriedades de uma classe ou protocolo podem ser dinamicamente introspectivas .

int ; _ 
int propriedadeCount = 0 ;   
objc_property_t * propertyList =  
    class_copyPropertyList ([ aPerson class ], & propertyCount );  

for ( i = 0 ; i < propertyCount ; i ++ ) {        
  objc_property_t * thisProperty = propertyList + i ;     
  const char * propertyName = property_getName ( * thisProperty );    
  NSLog ( @"Pessoa tem uma propriedade: '%s'" , propertyName ); 
}

Variáveis ​​de instância não frágeis

O Objective-C 2.0 fornece variáveis ​​de instância não frágeis quando suportadas pelo tempo de execução (ou seja, ao compilar código para macOS de 64 bits e todos os iOS). No tempo de execução moderno, uma camada extra de indireção é adicionada ao acesso à variável de instância, permitindo que o vinculador dinâmico ajuste o layout da instância em tempo de execução. Esse recurso permite duas melhorias importantes no código Objective-C:

  • Elimina o problema de interface binária frágil ; superclasses podem mudar de tamanho sem afetar a compatibilidade binária.
  • Ele permite que variáveis ​​de instância que fornecem o suporte para propriedades sejam sintetizadas em tempo de execução sem que elas sejam declaradas na interface da classe.

Enumeração rápida

Em vez de usar um objeto NSEnumerator ou índices para iterar por meio de uma coleção, o Objective-C 2.0 oferece a sintaxe de enumeração rápida. No Objective-C 2.0, os seguintes loops são funcionalmente equivalentes, mas possuem diferentes características de desempenho.

// Usando NSEnumerator 
NSEnumerator * enumerator = [ thePeople objectEnumerator ];    
Pessoa * p ; 

while (( p = [ enumerador nextObject ]) != nil ) {       
  NSLog ( @"%@ tem %i anos." , [ p nome ], [ p idade ]);    
}
// Usando índices 
for ( int i = 0 ; i < [ thePeople count ]; i ++ ) {          
  Pessoa * p = [ thePeople objectAtIndex : i ];    
  NSLog ( @"%@ tem %i anos." , [ p nome ], [ p idade ]);    
}
// Usando enumeração rápida 
para ( Person * p in thePeople ) {     
  NSLog ( @"%@ tem %i anos." , [ p nome ], [ p idade ]);    
}

A enumeração rápida gera um código mais eficiente do que a enumeração padrão porque as chamadas de método para enumerar objetos são substituídas por aritmética de ponteiro usando o protocolo NSFastEnumeration. [40]

Extensões de classe

Uma extensão de classe tem a mesma sintaxe que uma declaração de categoria sem nome de categoria, e os métodos e propriedades declarados nela são adicionados diretamente à classe principal. É usado principalmente como uma alternativa a uma categoria para adicionar métodos a uma classe sem anunciá-los nos cabeçalhos públicos, com a vantagem de que para extensões de classe o compilador verifica se todos os métodos declarados em particular estão realmente implementados. [41]

Implicações para o desenvolvimento do cacau

Todos os aplicativos Objective-C desenvolvidos para macOS que fazem uso das melhorias acima para Objective-C 2.0 são incompatíveis com todos os sistemas operacionais anteriores a 10.5 (Leopard). Como a enumeração rápida não gera exatamente os mesmos binários que a enumeração padrão, seu uso fará com que um aplicativo falhe no Mac OS X versão 10.4 ou anterior.

Blocos

Blocks é uma extensão não padrão para Objective-C (e C e C++ ) que usa sintaxe especial para criar closures . Os blocos são suportados apenas no Mac OS X 10.6 "Snow Leopard" ou posterior, iOS 4 ou posterior e GNUstep com libobjc2 1.7 e compilando com clang 3.1 ou posterior. [42]

#include <stdio.h> 
#include <Block.h> 
typedef int ( ^ IntBlock )();  

IntBlock MakeCounter ( int start , int increment ) {     
  __block int i = início ;    

  return Block_copy ( ^ {   
    int ret = i ;   
    i += incremento ;  
    retorno ret ; 
  });

}

int main ( void ) {  
  IntBlock meucontador = MakeCounter ( 5 , 2 );    
  printf ( "Primeira chamada: %d \n " , meucontador ()); 
  printf ( "Segunda chamada: %d \n " , meucontador ()); 
  printf ( "Terceira chamada: %d \n " , meucontador ()); 

  /* porque foi copiado, também deve ser liberado */
  Block_release ( meucontador );

  retorna 0 ; 
}
/* Saída: 
  Primeira chamada: 5 
  Segunda chamada: 7 
  Terceira chamada: 9 
*/

Modern Objective-C

A Apple adicionou alguns recursos adicionais ao Objetivo 2.0 ao longo do tempo. As adições só se aplicam ao "compilador Apple LLVM ", ou seja, o frontend clang da linguagem. Confusamente, o versionamento usado pela Apple difere daquele do LLVM upstream; consulte Xcode § Versões da cadeia de ferramentas para obter uma tradução para os números de versão LLVM de código aberto. [43]

Contagem Automática de Referências

A contagem automática de referência (ARC) é um recurso de tempo de compilação que elimina a necessidade de os programadores gerenciarem manualmente as contagens de retenção usando retaine release. [44] Ao contrário da coleta de lixo , que ocorre em tempo de execução, o ARC elimina a sobrecarga de um processo separado gerenciando contagens de retenção. ARC e gerenciamento manual de memória não são mutuamente exclusivos; os programadores podem continuar a usar código não ARC em projetos habilitados para ARC desabilitando o ARC para arquivos de código individuais. O Xcode também pode tentar atualizar automaticamente um projeto para o ARC.

O ARC foi introduzido no LLVM 3.0. Isso se traduz em Xcode 4.2 (2011) ou compilador Apple LLVM 3.0. [45]

Literais

Os tempos de execução NeXT e Apple Obj-C incluem há muito tempo uma forma abreviada de criar novas strings, usando a sintaxe literal @"a new string", ou descartar as constantes CoreFoundation kCFBooleanTruee kCFBooleanFalsefor NSNumbercom valores booleanos. O uso desse formato evita que o programador tenha que usar initWithStringmétodos mais longos ou semelhantes ao realizar determinadas operações.

Ao usar o compilador Apple LLVM 4.0 (Xcode 4.4) ou posterior, matrizes, dicionários e números ( NSArray, NSDictionary, NSNumberclasses) também podem ser criados usando sintaxe literal em vez de métodos. [46] (Compilador LLVM 4.0 da Apple converte para LLVM de código aberto e Clang 3.1.) [47]

Exemplo sem literais:

NSArray * myArray = [ NSArray arrayWithObjects : object1 , object2 , object3 , nil ];    
NSDictionary * myDictionary1 = [ NSDictionary dictionaryWithObject : someObject forKey : @"key" ];     
NSDictionary * myDictionary2 = [ NSDictionary dictionaryWithObjectsAndKeys : object1 , key1 , object2 , key2 , nil ];        
NSNumber * myNumber = [ NSNumber numberWithInt : myInt ];    
NSNumber * mySumNumber = [ NSNumber numberWithInt :( 2 + 3 )];     
NSNumber * myBoolNumber = [ NSNumber numberWithBool : YES ];    

Exemplo com literais:

NSArray * myArray = @[ object1 , object2 , object3 ] ;       
NSDictionary * myDictionary1 = @{ @"key" : someObject } ;       
NSDictionary * myDictionary2 = @{ key1 : object1 , key2 : object2 } ;        
NSNumber * myNumber = @( myInt ) ;   
NSNumber * mySumNumber = @( 2 + 3 ) ;   
NSNumber * myBoolNumber = @YES ;   
NSNumber * myIntegerNumber = @8 ;   

No entanto, diferente dos literais de string , que compilam para constantes no executável, esses literais compilam para um código equivalente às chamadas de método acima. Em particular, no gerenciamento de memória com contagem de referência manual, esses objetos são liberados automaticamente, o que requer cuidado adicional quando, por exemplo, usado com variáveis ​​estáticas de função ou outros tipos de globais.

Assinatura

Ao usar o compilador Apple LLVM 4.0 ou posterior, matrizes e dicionários ( NSArraye NSDictionaryclasses) podem ser manipulados usando subscritos. [46] A subscrição pode ser usada para recuperar valores de índices (array) ou chaves (dicionário), e com objetos mutáveis, também pode ser usada para definir objetos para índices ou chaves. No código, a subscrição é representada usando colchetes [ ]. [48]

Exemplo sem subscrição:

id object1 = [ someArray objectAtIndex : 0 ];    
id object2 = [ someDictionary objectForKey : @"key" ];    
[ someMutableArray replaceObjectAtIndex : 0 withObject : object3 ];  
[ someMutableDictionary setObject : object4 forKey : @"key" ];  

Exemplo com subscrição:

id objeto1 = someArray [ 0 ];   
id object2 = someDictionary [ @"key" ];   
someMutableArray [ 0 ] = object3 ;  
someMutableDictionary [ @"key" ] = object4 ;  

Sintaxe de Objective-C "moderna" (1997)

Após a compra do NeXT pela Apple, foram feitas tentativas para tornar a linguagem mais aceitável para programadores mais familiarizados com Java do que Smalltalk. Uma dessas tentativas foi introduzir o que foi apelidado de "Sintaxe Moderna" para Objective-C na época [49] (em oposição à sintaxe "clássica" atual). Não houve mudança de comportamento, esta foi apenas uma sintaxe alternativa. Em vez de escrever uma invocação de método como

    object = [[ MyClass alloc ] init ];    
    [ object firstLabel : param1 secondLabel : param2 ];    

Em vez disso, foi escrito como

    object = ( MinhaClasse . alloc ). inicial ;  
    objeto . rótulos ( param1 , param2 );    

Da mesma forma, as declarações passaram do formulário

    - ( void ) firstLabel : ( int ) param1 secondLabel : ( int ) param2 ;    

para

    - ( void ) rótulos ( int param1 , int param2 );       

Essa sintaxe "moderna" não é mais suportada nos dialetos atuais da linguagem Objective-C.

mulle-objc

O projeto mulle-objc é outra reimplementação do Objective-C. Ele suporta compiladores GCC ou Clang / LLVM como backends. Ele diverge de outros tempos de execução em termos de sintaxe, semântica e compatibilidade com ABI. Ele suporta Linux, FreeBSD e Windows.

Compilador de Objetos Portátil

Além da implementação GCC / NeXT / Apple , que adicionou várias extensões à implementação original do Stepstone , também existe outra implementação de Objective-C gratuita e de código aberto chamada Portable Object Compiler. [50] O conjunto de extensões implementadas pelo Portable Object Compiler difere da implementação GCC/NeXT/Apple; em particular, ele inclui blocos do tipo Smalltalk para Objective-C, embora não possua protocolos e categorias, dois recursos usados ​​extensivamente no OpenStep e seus derivados e parentes. No geral, o POC representa um estágio mais antigo, pré-NeXT, na evolução da linguagem, aproximadamente em conformidade com o livro de Brad Cox de 1991.

Ele também inclui uma biblioteca de tempo de execução chamada ObjectPak, que é baseada na biblioteca ICPak101 original de Cox (que por sua vez deriva da biblioteca de classes Smalltalk-80) e é radicalmente diferente do OpenStep FoundationKit.

GEOS Objective-C

O sistema PC GEOS usava uma linguagem de programação conhecida como GEOS Objective-C ou goc ; [51] apesar da semelhança do nome, as duas línguas são semelhantes apenas no conceito geral e no uso de palavras-chave prefixadas com um sinal @.

Clam

O conjunto de compiladores Clang , parte do projeto LLVM , implementa Objective-C e outras linguagens. Depois que o GCC 4.3 (2008) mudou para GPLv3, a Apple o abandonou em favor do clang, um compilador que tem mais poder legal para modificar. Como resultado, muitos dos recursos modernos da linguagem Objective-C são suportados apenas pelo Clang.

O esquema de versionamento da Apple para seu "compilador LLVM" baseado em clang difere do versionamento de código aberto do LLVM. Veja Xcode § Versões do Toolchain para uma tradução [43]

GNU, GNUstep e WinObjC

O projeto GNU tem, há muito tempo, se interessado em uma plataforma para portar programas NeXT e Obj-C. O ChangeLog para o diretório libobjc no GCC sugere que existia antes de 1998 (GCC 2.95), e seu README aponta para uma reescrita em 1993 (GCC 2.4). [52]

O código-fonte do frontend NeXT foi lançado desde que foi feito como parte do GCC, lançou a GNU Public License , que força os que fazem trabalhos derivados a fazê-lo. [ quando? ] A Apple continuou essa tradição ao lançar seu fork do GCC até o 4.2.1, após o que abandonou o compilador. Os mantenedores do GCC aceitaram as mudanças, mas não investiram muito no suporte a recursos mais novos, como a linguagem Objective-C 2.0. [32] : Qual compilador 

Os desenvolvedores do GNUstep, interessados ​​na nova linguagem, bifurcaram o GCC libobjc para um projeto independente do GCC chamado libobjc2 em 2009. Eles também organizaram o runtime a ser usado com o Clang para tirar vantagem da nova sintaxe da linguagem. [32] : Qual compilador  GCC moveu lentamente ao mesmo tempo, mas no GCC 4.6.0 (2011) eles mudaram para Objective-C 2.0 em seu libobjc também. [31] [53] A documentação do GNUstep sugere que a implementação do GCC ainda carece de suporte para blocos, variáveis ​​não frágeis e o ARC mais recente. [32] : Qual tempo de execução 

A Microsoft bifurcou o libobjc2 em uma parte do WinObjC , a ponte iOS para a Plataforma Universal do Windows , em 2015. Combinado com sua própria implementação do Cocoa Touch e APIs subjacentes, o projeto permite a reutilização do código do aplicativo iOS dentro de aplicativos UWP. [54]

No Windows, as ferramentas de desenvolvimento Objective-C são fornecidas para download no site da GNUStep. O Sistema de Desenvolvimento GNUStep consiste nos seguintes pacotes: GNUstep MSYS System, GNUstep Core, GNUstep Devel, GNUstep Cairo, ProjectCenter IDE (como Xcode, mas não tão complexo), Gorm (Interface Builder Like Xcode NIB builder). Esses instaladores binários não foram atualizados desde 2016, [55] portanto, seria uma ideia melhor instalar apenas compilando em Cygwin ou MSYS2 .

Uso da biblioteca

O Objective-C hoje é frequentemente usado em conjunto com uma biblioteca fixa de objetos padrão (geralmente conhecidos como "kit" ou "framework"), como Cocoa , GNUstep ou ObjFW . Essas bibliotecas geralmente vêm com o sistema operacional: as bibliotecas GNUstep geralmente vêm com o Linuxdistribuições baseadas e o Cocoa vem com o macOS. O programador não é obrigado a herdar a funcionalidade da classe base existente (NSObject / OFObject). Objective-C permite a declaração de novas classes raiz que não herdam nenhuma funcionalidade existente. Originalmente, os ambientes de programação baseados em Objective-C normalmente ofereciam uma classe Object como a classe base da qual quase todas as outras classes eram herdadas. Com a introdução do OpenStep, a NeXT criou uma nova classe base chamada NSObject, que oferecia recursos adicionais sobre Object (uma ênfase no uso de referências de objetos e contagem de referências em vez de ponteiros brutos, por exemplo). Quase todas as classes em Cocoa herdam de NSObject.

A renomeação não apenas serviu para diferenciar o novo comportamento padrão das classes dentro da API OpenStep, mas permitiu que o código que usava Object - a classe base original usada no NeXTSTEP (e, mais ou menos, outras bibliotecas de classes Objective-C) - coexistir no mesmo tempo de execução com o código que usou NSObject (com algumas limitações). A introdução do prefixo de duas letras também se tornou uma forma simplista de namespaces, que o Objective-C não possui. Usar um prefixo para criar um identificador de embalagem informal tornou-se um padrão de codificação informal na comunidade Objective-C e continua até hoje.

Mais recentemente, começaram a aparecer gerenciadores de pacotes, como o CocoaPods , que pretende ser tanto um gerenciador de pacotes quanto um repositório de pacotes. Muito do código Objective-C de código aberto que foi escrito nos últimos anos agora pode ser instalado usando CocoaPods.

Análise da linguagem

As implementações de Objective-C usam um sistema de tempo de execução fino escrito em C [ citação necessária ] , que adiciona pouco ao tamanho do aplicativo. Em contraste, a maioria dos sistemas orientados a objetos na época em que foram criados usavam grandes máquinas virtuaistempos de execução. Programas escritos em Objective-C tendem a não ser muito maiores que o tamanho de seu código e o das bibliotecas (que geralmente não precisam ser incluídas na distribuição de software), em contraste com sistemas Smalltalk onde uma grande quantidade de memória era usado apenas para abrir uma janela. Aplicativos Objective-C tendem a ser maiores do que aplicativos C ou C++ semelhantes porque a tipagem dinâmica Objective-C não permite que os métodos sejam removidos ou embutidos. Uma vez que o programador tem tanta liberdade para delegar, encaminhar chamadas, construir seletores em tempo real e passá-los para o sistema de tempo de execução, o compilador Objective-C não pode assumir que é seguro remover métodos não utilizados ou chamadas inline.

Da mesma forma, a linguagem pode ser implementada em compiladores C existentes (no GCC , primeiro como um pré-processador, depois como um módulo) em vez de um novo compilador. Isso permite que Objective-C aproveite a enorme coleção existente de código C, bibliotecas, ferramentas, etc. Bibliotecas C existentes podem ser encapsuladas em wrappers Objective-C para fornecer uma interface de estilo OO. Nesse aspecto, é semelhante à biblioteca GObject e à linguagem Vala , que são amplamente utilizadas no desenvolvimento de aplicações GTK .

Todas essas mudanças práticas reduziram a barreira de entrada , provavelmente o maior problema para a ampla aceitação do Smalltalk na década de 1980.

Uma crítica comum é que Objective-C não tem suporte de linguagem para namespaces . Em vez disso, os programadores são forçados a adicionar prefixos aos seus nomes de classe, que são tradicionalmente mais curtos do que os nomes de namespace e, portanto, mais propensos a colisões. A partir de 2007, todas as classes e funções do macOS no ambiente de programação Cocoa são prefixadas com "NS" (por exemplo, NSObject, NSButton) para identificá-las como pertencentes ao núcleo do macOS ou iOS; o "NS" deriva dos nomes das classes conforme definido durante o desenvolvimento do NeXTSTEP .

Como Objective-C é um superconjunto estrito de C, ele não trata tipos primitivos de C como objetos de primeira classe .

Ao contrário do C++ , Objective-C não suporta sobrecarga de operadores . Também diferente de C++, Objective-C permite que um objeto herde diretamente apenas de uma classe (proibindo herança múltipla ). No entanto, na maioria dos casos, categorias e protocolos podem ser utilizados como formas alternativas para alcançar os mesmos resultados.

Como Objective-C usa tipagem dinâmica em tempo de execução e porque todas as chamadas de método são chamadas de função (ou, em alguns casos, syscalls), muitas otimizações de desempenho comuns não podem ser aplicadas a métodos Objective-C (por exemplo: inlining, constante propagação, otimizações interprocedural, e substituição escalar de agregados). Isso limita o desempenho de abstrações de Objective-C em relação a abstrações semelhantes em linguagens como C++, onde essas otimizações são possíveis.

Gerenciamento de memória

As primeiras versões do Objective-C não suportavam a coleta de lixo . Na época, essa decisão foi motivo de algum debate, e muitas pessoas consideraram longos "tempos mortos" (quando Smalltalk realizava a coleta) para tornar todo o sistema inutilizável. Algumas implementações de terceiros adicionaram esse recurso (mais notavelmente GNUstep usando Boehm ), e a Apple o implementou a partir do Mac OS X v10.5 . [56] No entanto, em versões mais recentes do macOS e iOS, a coleta de lixo foi preterida em favor da Contagem Automática de Referência (ARC), introduzida em 2011.

Com o ARC, o compilador insere chamadas de retenção e liberação automaticamente no código Objective-C com base na análise de código estático . A automação alivia o programador de ter que escrever no código de gerenciamento de memória. O ARC também adiciona referências fracas à linguagem Objective-C. [57]

Diferenças filosóficas entre Objective-C e C++

O design e a implementação de C++ e Objective-C representam abordagens fundamentalmente diferentes para estender C.

Além do estilo de programação procedural do C, o C++ suporta diretamente certas formas de programação orientada a objetos , programação genérica e metaprogramação . C++ também vem com uma grande biblioteca padrão que inclui várias classes de contêiner . Da mesma forma, Objective-C adiciona programação orientada a objetos , tipagem dinâmica e reflexão a C. Objective-C não fornece uma biblioteca padrão per se , mas na maioria dos lugares onde Objective-C é usado, ele é usado com um OpenStep -like biblioteca como OPENSTEP , Cocoa ou GNUstep, que fornece funcionalidade semelhante à biblioteca padrão do C++.

Uma diferença notável é que Objective-C fornece suporte de tempo de execução para recursos reflexivos , enquanto C++ adiciona apenas uma pequena quantidade de suporte de tempo de execução a C. Em Objective-C, um objeto pode ser consultado sobre suas próprias propriedades, por exemplo, se ele responderá a uma determinada mensagem. Em C++, isso não é possível sem o uso de bibliotecas externas.

O uso de reflexão é parte da distinção mais ampla entre recursos dinâmicos (tempo de execução) e recursos estáticos (tempo de compilação) de uma linguagem. Embora Objective-C e C++ empreguem uma mistura de ambos os recursos, Objective-C é decididamente voltado para decisões em tempo de execução, enquanto C++ é voltado para decisões em tempo de compilação. A tensão entre programação dinâmica e estática envolve muitos dos trade-offs clássicos na programação: recursos dinâmicos adicionam flexibilidade, recursos estáticos adicionam velocidade e verificação de tipo.

A programação genérica e a metaprogramação podem ser implementadas em ambas as linguagens usando polimorfismo de tempo de execução . Em C++, isso assume a forma de funções virtuais e identificação de tipo de tempo de execução , enquanto Objective-C oferece tipagem dinâmica e reflexão. Tanto o Objective-C quanto o C++ dão suporte ao polimorfismo de tempo de compilação ( funções genéricas ), com o Objective-C adicionando esse recurso apenas em 2015.

Veja também

Referências

  1. ^ "Versões e plataformas de tempo de execução" . Developer.apple . com . Arquivado do original em 20 de julho de 2016 . Recuperado em 24 de dezembro de 2017 .
  2. ^ Lattner, Chris (3 de junho de 2014). "Homepage de Chris Lattner" . Chris Latner. Arquivado do original em 4 de junho de 2014 . Recuperado em 3 de junho de 2014 . A linguagem Swift é o produto do esforço incansável de uma equipe de especialistas em linguagem, gurus de documentação, ninjas de otimização de compiladores e um grupo interno incrivelmente importante de dogfooding que forneceu feedback para ajudar a refinar e testar ideias. Claro, também se beneficiou muito das experiências duramente conquistadas por muitas outras linguagens no campo, extraindo ideias de Objective-C, Rust, Haskell, Ruby, Python, C#, CLU e muitos outros para listar.
  3. ^ Singh, Amit (dezembro de 2003). "Uma Breve História do Mac OS X" . Internos do Mac OS X. Arquivado do original em 14 de maio de 2012 . Recuperado em 11 de junho de 2012 .
  4. ^ "Estruturas de aplicativos" . Maçã. Junho de 2014. Arquivado a partir do original em 16 de fevereiro de 2019 . Recuperado em 13 de fevereiro de 2019 .
  5. ^ Garling, Calebe. "IPhone Coding Language agora é o terceiro mais popular do mundo" . Com fio . Arquivado do original em 9 de setembro de 2013 . Recuperado em 20 de maio de 2013 .
  6. ^ Wentk, Richard (2009). Cacau: Volume 5 da Referência do Desenvolvedor Apple Developer Series . John Wiley e Filhos. ISBN 978-0-470-49589-6. Arquivado do original em 16 de fevereiro de 2017 . Recuperado em 22 de julho de 2016 .
  7. ^ Biancuzzi, Federico; Diretor, Shane (2009). Mestres da Programação . O'Reilly Media, Inc. pp. 242-246. ISBN 978-0-596-51517-1. Arquivado do original em 17 de fevereiro de 2017 . Recuperado em 22 de julho de 2016 .
  8. ^ Cox, Brad (1983). "O pré-compilador orientado a objetos: programando métodos Smalltalk 80 em linguagem C" . Avisos ACM SIGPLAN . Nova York, NY: ACM . 18 (1). doi : 10.1145/948093.948095 . S2CID 6975032 . Recuperado em 17 de fevereiro de 2011 . 
  9. ^ "Common Lisp e Readline" . Arquivado do original em 6 de setembro de 2014 . Recuperado em 15 de setembro de 2014 .O problema surgiu pela primeira vez quando a NeXT propôs distribuir um GCC modificado em duas partes e deixar o usuário vinculá-las. Jobs me perguntou se isso era legal. Pareceu-me na época que era, seguindo um raciocínio como o que você está usando; mas como o resultado era muito indesejável para o software livre, eu disse que teria que perguntar ao advogado. O que o advogado disse me surpreendeu; ele disse que os juízes considerariam tais esquemas como "subterfúgios" e seriam muito duros com eles. Ele disse que um juiz perguntará se é "realmente" um programa, em vez de como ele é rotulado. Então voltei a Jobs e disse que acreditávamos que seu plano não era permitido pela GPL. O resultado direto disso é que agora temos um front-end do Objective C.
  10. ^ "GNUstep: Introdução" . Desenvolvedores GNUstep/Projeto GNU. Arquivado a partir do original em 6 de agosto de 2012 . Recuperado em 29 de julho de 2012 .
  11. ^ "Kresten Krab Thorup | LinkedIn" . www.linkedin.com . Arquivado do original em 15 de julho de 2014 . Recuperado em 23 de junho de 2016 .
  12. ^ "Escrever código Objective-C" . apple. com. 23 de abril de 2013. Arquivado a partir do original em 24 de dezembro de 2013 . Recuperado em 22 de dezembro de 2013 .
  13. ^ "Objetivo-C Boot Camp" . Arquivado do original em 11 de fevereiro de 2018 . Recuperado em 11 de fevereiro de 2018 . Objective-C é um superconjunto estrito de ANSI C
  14. ^ "Examinando Objective-C" . Arquivado a partir do original em 4 de setembro de 2014 . Recuperado em 4 de setembro de 2014 . Objective-C é um superconjunto estrito orientado a objetos de C
  15. ^ Lee, Keith (3 de setembro de 2013). Pro Objective-C . Apress. ISBN 9781430250500. Arquivado do original em 14 de maio de 2018 . Recuperado em 24 de dezembro de 2017 – via Google Livros.
  16. ^ "Tags para cabeçalhos Objective-C" . Arquivado a partir do original em 1º de abril de 2017 . Recuperado em 11 de fevereiro de 2018 . Objective-C é um superconjunto de C
  17. ^ "AppScan Source 8.7 agora disponível" . Arquivado do original em 3 de fevereiro de 2017 . Recuperado em 11 de fevereiro de 2018 . A linguagem de programação Objective-C é um superconjunto da linguagem de programação C
  18. ^ Apple, Inc. (19 de outubro de 2009). "Resolução de Método Dinâmico" . Guia de programação em tempo de execução do Objective-C . Arquivado do original em 7 de setembro de 2010 . Recuperado em 25 de novembro de 2014 .
  19. ^ Apple, Inc. (19 de outubro de 2009). "Evitando erros de mensagens" . A linguagem de programação Objective-C . Arquivado a partir do original em 8 de setembro de 2010.
  20. ^ "objc_msgSend - Tempo de execução do Objective-C" . Documentação do desenvolvedor da Apple . Recuperado em 10 de fevereiro de 2020 .
  21. ^ "Mensagens com o tempo de execução GNU Objective-C" . Usando o GNU Compiler Collection (GCC) . Recuperado em 10 de fevereiro de 2020 .
  22. ^ "Categoria" . Desenvolvedor Apple (Cocoa Core Competencies) .
  23. ^ Dalrymple, Mark; Knaster, Scott (27 de junho de 2012). Aprenda Objective-C no Mac . pág. 9. ISBN 9781430241881. A extensão .m originalmente significava "mensagens" quando o Objective-C foi introduzido pela primeira vez, referindo-se a um recurso central do Objective-C
  24. ^ "Guia de programação do tempo de execução do Objective-C" . Apple Inc. Arquivado a partir do original em 4 de abril de 2014 . Recuperado em 21 de outubro de 2013 .
  25. ^ "ACM SIGGRAPH 1983 Edição 8 - Smalltalk" . Arquivado a partir do original em 15 de abril de 2009 . Recuperado em 7 de outubro de 2008 .
  26. ^ "Métodos de extensão (guia de programação C#)" . Microsoft. Outubro de 2010. Arquivado a partir do original em 11 de julho de 2011 . Recuperado em 10 de julho de 2011 .
  27. ^ "Usando C++ com Objective-C" . Biblioteca de referência do Mac OS X . Arquivado a partir do original em 5 de setembro de 2010 . Recuperado em 10 de fevereiro de 2010 .
  28. ^ "Extensões de linguagem Clang - documentação Clang 3.5" . Clang.llvm.org. Arquivado do original em 24 de fevereiro de 2014 . Recuperado em 16 de abril de 2014 .
  29. ^ "Objective-C 2.0: mais pistas" . Lists.apple.com. 10 de agosto de 2006. Arquivado a partir do original em 18 de junho de 2009 . Recuperado em 30 de maio de 2010 .
  30. ^ "Re: Objetivo-C 2.0" . Lists.apple.com. Arquivado a partir do original em 24 de novembro de 2010 . Recuperado em 30 de maio de 2010 .
  31. ^ a b "GCC 4.6 Release Series — Mudanças, Novos Recursos e Correções: Projeto GNU: Fundação de Software Livre" . Gcc.gnu.org . Arquivado a partir do original em 5 de janeiro de 2018 . Recuperado em 24 de dezembro de 2017 .
  32. ^ a b c d "ObjC2 FAQ" . GNUstep . Recuperado em 6 de janeiro de 2020 .
  33. ^ "Navegador de origem: objc4, 756.2" . Código aberto da Apple . Recuperado em 6 de janeiro de 2020 .
  34. ^ Guia de programação de coleta de lixo: API de coleta de lixo Arquivado em 5 de junho de 2012, no WebCite (site do desenvolvedor da Apple - procure por "__strong")
  35. ^ "Guia de programação da coleta de lixo: Introdução à coleta de lixo" . Apple Inc. 3 de outubro de 2011. Arquivado a partir do original em 5 de junho de 2012 . Recuperado em 23 de dezembro de 2011 .
  36. ^ "Série da tecnologia do leopardo para desenvolvedores: visão geral do Objective-C 2.0" . Apple Inc. 6 de novembro de 2007. Arquivado a partir do original em 24 de julho de 2010 . Recuperado em 30 de maio de 2010 .
  37. ^ "Transição para ARC Release Notes" . Apple Inc. 17 de julho de 2012. Arquivado a partir do original em 5 de junho de 2012 . Recuperado em 26 de agosto de 2012 .
  38. ^ Mike Ash. "Sexta-feira Q&A 2013-09-27: ARM64 e você" . mikeash. com. Arquivado do original em 26 de abril de 2014 . Recuperado em 27 de abril de 2014 .
  39. ^ "Hamster Emporium: [objc explicar]: Non-pointer isa" . Sealiesoftware. com. 24 de setembro de 2013. Arquivado a partir do original em 3 de junho de 2014 . Recuperado em 27 de abril de 2014 .
  40. ^ Apple, Inc. (2009). "Enumeração Rápida" . apple. com. Arquivado do original em 17 de dezembro de 2009 . Recuperado em 31 de dezembro de 2009 .
  41. ^ Free Software Foundation, Inc. (2011). "GCC 4.6 Release Series - Alterações, novos recursos e correções" . Gcc.gnu.org . Arquivado do original em 2 de dezembro de 2013 . Recuperado em 27 de novembro de 2013 .
  42. ^ "Tópicos de Programação de Blocos - Biblioteca do Desenvolvedor Mac" . Apple Inc. 8 de março de 2011. Arquivado a partir do original em 5 de junho de 2012 . Recuperado em 28 de novembro de 2012 .
  43. ^ a b "Contagem automática de referência do Objectivo-C (ARC) — documentação do Clang 11" . Documentação do Clang . Recuperado em 20 de fevereiro de 2020 . Por enquanto, é sensato a versão deste documento pelos lançamentos de sua única implementação (e seu projeto host), clang. “LLVM XY” refere-se a uma versão de código aberto do clang do projeto LLVM. “Apple XY” refere-se a uma versão fornecida pela Apple do Apple LLVM Compiler.
  44. ^ "Transição para ARC" . Apple Inc. Arquivado a partir do original em 7 de setembro de 2011 . Recuperado em 8 de outubro de 2012 .
  45. ^ "Notas de versão do LLVM 3.0" . releases.llvm.org .
  46. ^ a b "Programação com Objective-C: Valores e coleções" . Apple Inc. Arquivado a partir do original em 7 de setembro de 2011 . Recuperado em 8 de outubro de 2012 .
  47. ^ "Notas de lançamento do Clang 3.1" . releases.llvm.org .
  48. ^ "Literais Objectivo-C - Documentação Clang 3.5" . Clang.llvm.org. Arquivado do original em 6 de junho de 2014 . Recuperado em 16 de abril de 2014 .
  49. ^ Guia do desenvolvedor Rhapsody , AP Professional, 1997, pp. 76-84
  50. ^ "Compilador de Objetos Portátil" . Users.pandora.be. 1º de janeiro de 1970. Arquivado a partir do original em 2 de agosto de 2008 . Recuperado em 30 de maio de 2010 .
  51. ^ "Página inicial da Breadbox Computer Company LLC" . Arquivado a partir do original em 27 de julho de 2011 . Recuperado em 8 de dezembro de 2010 .
  52. ^ "gcc/libobjc" . GitHub . gcc-espelho. 6 de janeiro de 2020 . Recuperado em 6 de janeiro de 2020 . O tempo de execução foi completamente reescrito no gcc 2.4. O tempo de execução anterior tinha vários bugs graves e era bastante incompleto.
  53. ^ "API de tempo de execução GNU Objective-C" . Usando o GCC . Recuperado em 6 de janeiro de 2020 .
  54. ^ "WinObjC no GitHub" . GitHub . Arquivado do original em 2 de dezembro de 2017 . Recuperado em 13 de fevereiro de 2018 .
  55. ^ "Instalador GNUStep" . Arquivado do original em 17 de fevereiro de 2018 . Recuperado em 14 de fevereiro de 2018 .
  56. ^ Apple, Inc. (22 de agosto de 2006). "Mac OS X Leopard – Xcode 3.0" . apple. com. Arquivado a partir do original em 24 de outubro de 2007 . Recuperado em 22 de agosto de 2006 .
  57. ^ "Transição para ARC Release Notes" . Biblioteca do desenvolvedor iOS . Developer.apple. com. Arquivado a partir do original em 7 de setembro de 2011 . Recuperado em 16 de abril de 2014 .

Leitura adicional

  • Cox, Brad J. (1991). Programação Orientada a Objetos: Uma Abordagem Evolucionária . Addison Wesley. ISBN 0-201-54834-8.

Links externos