Sunteți pe pagina 1din 27

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

&

Maurício&Linhares &

Desenvolvendo ) aplicações)para)iOS)usando)Objective 7 C )

DESENVOLVIMENTO+DE+A PLICAÇÕES+PARA+IOS+U SANDO+OBJECTIVE 5 C +

1 &

I NTRODUÇÃO +

2

C APÍTULO+ 1 + 5 + C ONHECENDO+ O BJECTIVE 5 C +

3

I

MAGEM& 1 & & S ELEÇÃO&DE&PROJETOS&N O& XC ODE &

3

I

MAGEM& 2 & & C

RIANDO&O&PROJETO&NO& X CODE& &

4

I

MAGEM& 3 & & V

ISUALIZAÇÃO&INICIAL& DO&PROJETO &

5

I

MAGEM& 4 & & C

RIANDO&O&TARGET&QUE& VAI&RODAR&OS&NOSSOS& T ESTES &

6

I MAGEM& 5 & & A DICIONANDO&O&EXECUTÁ VEL&DA&APLICAÇÃO&COM O&DEPENDÊNCIA&AO&TAR GET& T EST & 7 &

I

MAGEM& 6 & & C

RIANDO&A&NOSSA&PRIME

RIANDO&A&NOSSA&PRIME

IRA&CLASSE&EM& O

BJECTIVE 8 C

8

I

MAGEM& 7 & & C

IRA&CLASSE&EM& O

BJECTIVE 8 C

9

I

MAGEM& 8 & & VISUALIZAÇÃO&DO&NAVE GADOR&DE&ARQUIVOS&CO M&A&CLASSE& C ONTA&CRIADA . &

9

L ISTAGEM& 1 & & C ONTA . H &

 

9

L

ISTAGEM& 2 & & C

ONTA . M &

11

L

ISTAGEM& 3 & & C

ONTA . H &

11

L

ISTAGEM& 4 & & C

ONTA . M &

12

C

RIANDO+O+NOSSO+PRIME IRO+TESTE+UNITÁRIO +

 

12

I

MAGEM& 9 & & C RIANDO&O&GRUPO& T EST &

 

13

I

MAGEM& 10 & & C

RIANDO&A&CLASSE&DE&T ESTES &

 

13

I

MAGEM& 11 & & S

ELECIONANDO&OS&TARGE TS&DA&CLASSE&DE&TEST ES

14

I

MPLEME NTANDO+O+NOSSO+PRIME IRO+TESTE +

 

14

L ISTAGEM& 5 & & C ONTA T EST . M

 

14

I

MAGEM& 12 & & A LTERANDO&O&

T ARGET&PADRÃO&PARA& T EST &

 

16

I

MAGEM& 13 & & D RAG&E&DROP&DO&ARQUIV O& “C ONTA . M & EM& T EST &

16

I

MAGEM& 14 & & I NDICAÇÃO&DE&ERROS&DE & BUILD&DO& X CODE &

17

I

MAGEM& 15 & & TELA&DE&ERROS&NO&BUI LD&DO& X CODE &

18

L

L

L

ISTAGEM& 6 & & C ISTAGEM& 7 & & C

ISTAGEM& 8 & &

C

ONTA . H & ONTA . M & ONTA T EST . H &

18

19

20

L

ISTAGEM&& 9 & &

C ONTA T EST . M &

20

C

RIANDO+UM+ CONSTRUTOR + PARA+O+NOSSO+OBJETO+ CONTA +

 

22

L

ISTAGEM& 10 & & C

ONTA . H& &

DECLARANDO&O&MÉTODO& INIT W ITH S

ALDO &

22

L

ISTAGEM& 11 & & C

ONTA . M &

23

D EFININDO+PROPRIEDADE

S+AUTOMATICAMENTE+NO S+OBJETOS +

 

23

L

ISTAGEM+ 12 + + C ONTA . H+COM+A S+NOVAS+PROPRIEDADES + DEFINIDAS +

24

L ISTAGEM& 13 & & C ONTA . M&COM&A&DEFINIÇÃO&DA S&PROPRIEDADES&E&GER ENCIAMENTO&DE&MEMÓRI A & 25 &

L ISTAGEM& 14 & – & C ONTA T EST . M&COM&O&CÓDIGO&DE&GE RENCIAMENTO&DE&MEMÓR
L
ISTAGEM& 14 & – & C
ONTA T EST . M&COM&O&CÓDIGO&DE&GE RENCIAMENTO&DE&MEMÓR IA &
26
&
&
)
)

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

&

Introdução )

Maurício&Linhares &

Este&material&tem&como&objetivo&servir&de&referência&para&o&curso&de& desenvolvimento&de&aplicações&usando&Objective8 C&e&XCode&para&iOS,&o&sistema& operacional&&para&dispositivos&móveis&da&Apple,&como&iPhones,&iPods&e&iPads.& Ele& faz&parte&do&material&complementar&para&as&aulas&expositivas&do&curso&de& desenvolvimento&para&iOS.&

Para&seguir&esse&material&você&precisa&de&um&computador&com&MacOS&e&XCode& instalados,&além&do&SDK&para&desenvolvimento&de&aplicações&para&iOS.& O&material& também&assume&que&você&já&tem&ex periência&com&o&desenvolvimento&de& software&em&ao&menos&uma&linguagem&orientada&a&objetos. & &

Conceitos&básicos&de&programação&orientada&a&objetos&como&variáveis&de& instância,&métodos,&construtores,&herança,&encapsulamento&não&vão&ser& explicados,&assume8 se&que&quem&está&lendo&o&material&já&tem&conhecimento&de& todos&esses&conceitos&que&são&lugar&comum&em&qualquer&linguagem&de& programação&orientada&a&objetos.&

Em&várias&partes&do&material&você&vai&encontrar&a&fala&“Abra&o&menu&contextual& do&item&X” & ou&“clique&co m&o&botão&direito&em&X” , & isso&quer&dizer&usar&o&botão& direito&do&mouse&(em&um&mouse&comom) & fazer&“Control& +& Click”&no& item& selecionado & ou,&se&voc ê&estiver&usando&um&trackpad&mu lti8 touch,&clicar&com&os& dois&dedos&ao&mesmo&tempo.&

)

)

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Capítulo)1) 7 ) Conhecendo)Ob jective 7 C )

O&código&fonte&deste&primeiro&cap ítulo&est á & disponível&em& 8 & https://github.com/mauricio/capitulo8 18 curso8 ios& &

Objective 8 C&é&uma&linguagem&de&programação& orientada&a&objetos&de&uso&geral&e& é&a&língua&padrão&para&o&desenvolvimento&de&aplicações&para&o&Mac&OS&e&hoje& também&para&o&iOS,&ambos&sistemas&operacionais&desenvolvidos&pela&Apple.&A& linguagem&é&deriv ada&diretamente&do&C,&com&algumas&características&de& Smalltalk,&como&o&uso&de&parâmetros&dentro&do&nome&do&método&em&vez&de&em& uma&seção&de&parâmetros&no&mesmo.&

Vamos&fazer&agora&dar&os&nossos&primeiros&passos&com&o&XCode,&criando&um& projeto.&Abra&o&XCode,& essa&deve&ser&a&primeira&janela&que&você&vai&ver:&

Imagem)1)– ) Seleção)de)projetos)no)XCode)

&
&

Nessa&página,&selecione&“Create&a&new&Xcode&project”,&aqui&está&a&próxima&janela& que&você&vai&ver: &

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)2)– ) Criando)o)projeto)no)Xcode )

)
)

Nesse&primeiro&momento,&vamos&iniciar&com&uma&aplicação&para&MacOS,&pra& entender&o&funcionamento&da&linguagem&e&nos&acostumarmos&com&o&Xcode&como& ferramenta.&Após&selecionar&“Mac&OS&X”& 8 >&“Application”& 8 >&“Command& Line& Tool” ,&além&de&selecionar&“Foundation ”&no&campo&de&seleção.&Dê& o&nome& & “AprendendoObjectivec” & ao&projeto . &

Com&o&projeto&criado,&você&deve&ver&uma&janela&como&essa&agora:&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)3)– ) Visualização)inicial)do)projeto )

&
&

Um&fator&interessante&ao&se&iniciar&o&desenvolvimento&usando&Xcode&é&que& mesmo& se&parecendo&com&pastas,&“Source”,&“Documentation”,&“External& frameworks&and&libraries”&e&“Products”&não&são&pastas,&mas&“agrupamentos”&de& conteúdo.&Se&você&for&até&a&pasta&que&está&o&projeto,&vai&perceber&que&não& existem&diretórios&equivalentes&a&eles,&isso&acontece&porque&o&Xcode&organiza&os& arquivos&apenas&logicamente&e&não&fisicamente&dentro&do&projeto.&

Com&o&nosso&projeto&criado,&vamos&criar&um&target&para&os&testes&unitários&que& vamos&escrever&durante&o&exemplo.&Pra&fazer&isso,&clique&com&o&botão&direito&ou& “Control&&+&Click”&no&marcador&“Targets”,&siga&para&“Add”,&depois&“New&Target”.& Você&deve&ver&a&tela&abaixo: &

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)4)– ) Criando)o)target)que)vai)rodar)os)nossos)testes )

&
&

Ao&partir&pra&próxima&tela&você&vai&definir&o&nome&do&target,&coloque&o&nome& Test.&Assim&que&o&target&for&criado,&ele&vai&abrir&a&janela&de&opções&do&mesmo,& nela,&selecione&a&aba& “General”,&clique&no&botão&“+”,&você&deve&ver&então&uma& janela&como&a&imagem&logo&abaixo,&selecione&“AprendendoObjectivec”&e&clique& em&“Add&Target”. &

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem) 5) – ) Adicionando)o)executável)da)aplicação)como)dependência)ao)target) Test)

&
&

Estamos&agora&finalmente&prontos&pra&começar&a&escrever&o&código&do&projeto.& Para & entender&as&construções&básicas&da&linguagem,&vamos&criar&uma&classe& Conta&que&guarde&os&dados&de& agência,&número&de&conta,&banco&e&saldo.&Além& disso&a&classe&também&vai&conter&os&métodos&para&sacar,&depositar&e&transferir& dinheiro&entre&contas.&

Selecione&o&grupo&“Source”&e&abra&o&menu&contextual.&Vá&em&“Add”& 8 >&“New&File”.& Selecione&“Cocoa&Class”&e&depois&“Objective8 C&class”,&como&na&imagem&abaixo:&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)6)– ) Criando)a)nossa)primeira)classe)em)Objective 7 C )

&
&

Na&próxima&janela,&coloque&o&nome&da&classe&como&sendo&“Conta.m”& e&marque&o& checkbox&“Also&create&‘ Conta .h’”:&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)7)– ) Criando)a)nossa)primeira) classe)em)Objective 7 C )

&
&

Com&a&classe&criada,&você&deve&ver&os&arquivos&no&Xcode&como&na&imagem&abaixo:&

Imagem)8)– ) visualização)do)navegador)de)arquivos)com)a)classe)Conta)criada. )

&
&

Olhando&pra&essa& imagem&podemos&ver&que&existe&um&arquivo&“Conta.m”&e&um& arquivo&“Conta.h”,&vejamos&o&que&há&de&código&em&cada&um&desses&arquivos:&

Listagem)1)– ) Conta.h )

#import <Cocoa/Cocoa.h>

@interface Conta : NSObject {

}

@end

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Se&você&nunca&programou&em&C&na&vida,&deve&estar&se&perguntando& porque&temos& dois&arquivos&para&uma & única&classe,&um&“.h”&e&outro&“.m” .&O&arquivo&“.h”,& funciona&como&“cabeçalho”&(daí&o&“.h”,&de&“header”),&nele&você&define&a&interface& pública&da&classe,&como&os&atributos&que&ela&tem&e&os&métodos&que&ela& implementa&(e&que&devem&ficar&visíveis&para&terceiros).&

Em&Objective8 C,&diferentemente&de&Java&e&outras&linguagens,&não&existem& modificadores&de&nível&de&visibilidade&para&as&classes&ou&os&seus&membros&(como& métodos&e&atributos),&tudo&é&“visível”,&mas&apenas&o&que&estiver&definido&no& arquivo&“.h”&fica&real mente&disponível&para&outros&objetos&que&queiram&usar&a& sua&classe. &

Olhando&agora&diretamente&para&o&código&fonte,&vemos&o&“ #import( <Cocoa/Cocoa.h>”,( isso&quer&dizer&que&a&nossa&classe&está&declarando&que&vai& utilizar&funcionalidades&do&framework&“ Cocoa”&(na&verdade&nós&só&precisamos& do&framework&“ Foundation ”,&mas&vamos&deixar&assim&por&enquanto).&Logo&após& isso&vemos&o&seguinte&código:&

@interface(Conta(:(NSObject (

Sempre&que&você&vir&um&caractere&“@”&(arroba)&em&código&escrito&em&Objective8

C,&quer&dizer&que & o&que&vem&logo&após&ele&é&uma&extensão&da&linguagem&ao&C. &

Opa,&peraí,&como&assim&uma&“extensão&a&linguagem&C”? &

Objective 8 C,&assim&como&C++,&existe&como&uma&extensão&a&linguagem&C.&Você& pode&escrever&código&C&dentro&de&programas&escritos&em&Objective8 C&e&o& seu& código&(teoricamente)&vai&compilar&e&funcionar&normalmente.&Os&designers&da& linguagem&resolveram&então&definir&uma&forma&de&deixar&claro&o&que&não&é&“C& puro”&na&linguagem&usando&o&caracter&“@”.&Então&sempre&que&você&vir&o&“@”&já& sabe&que&isso&é&uma&ex tensão&do&Objective 8 C&para&adicionar&novos& comportamentos&ao&nosso&querido&e&amado&C.&

A&extensão& @interface& diz&que&estamos&definindo&uma&nova&classe&na&linguagem& e&o&que&segue&essa&declaração&é&o&nome&da&classe,&no&nosso&caso&“ Conta”.&Logo& após&a&declaraç ão&do&nome&da&classe&o&“:& NSObject ”&diz&que&a&nossa&classe&“ Conta”& herda&de&“ NSObject ”.&Diferentemente&de&outras&linguagens&onde&existe&uma&única& classe&raiz&e&mãe&de&todos&os&objetos&(pense&no&Object&de&Java,&Ruby,&C#&e&tantas& outras),&em&Objective8 C&você & mesmo&pode&definir&uma&classe&raiz,&mas& normalmente&você&vai&herdar&de&“ NSObject ”&que&é&a&classe&raiz&do&framework& base&de&Objective 8 C&utilizado&no&desenvolvimento&de&aplicações&para&o&Mac&OS&e& iOS.& Obviamente,&se&você&não&disser&de&qual&classe&você&herda,&a&sua&classe&se& torna&automaticamente&uma&classe&raiz,&então&lembre8 se&sempre&de&definir&a& superclasse&da&sua&classe&ou&simplesmente&coloque&que&ela&herda&de&“ NSObject ”. &

O&par&de&chaves&“{}”&que&ve m&logo&após&a&declaração&da&classe&é&o&lugar&onde& você&define&as&variáveis&de&instância&da&sua&classe&e&somente&elas&(não,&não&é& aqui&que&você&coloca&os&métodos).&Todas&as&variáveis&de&instância&precisam&estar& definidas&aqui&no&arquivo&“.h”,&mesmo&aquelas& que&você&queira&deixar&como& “privadas”. &

Após&o&par&de&chaves&vem&o&corpo&da&classe,&que&é&o&lugar&onde&você&define&os&

métodos&que&essa&classe&implementa&(mas&você&não&os&implementa&aqui,&você&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

apenas&define&quais&são&eles) .&Não&definir&um&método&aqui&normal mente&faz&com& que&não&seja&possível&pra&que&alguém&o&invoque,&é&uma&das&formas&de&se&criar& métodos&“privados”&em&Objective8 C,&já&que&não&existe&esse&conceito&dentro&da& linguagem&em&si. &

Listagem)2)– ) Conta.m )

#import "Conta.h"

@implementation Conta

@end

& No&arquivo&“.m”&você&encontra&agora&o&código&real&da&classe&(mesmo&que&não& tenhamos&colocado&nada&ainda&nele.&Enquanto&que&no&arquivo&“.h”&nós&havíamos& definido&a& @interface& do&código,&agora&estamos&definindo&a& @implementation .& Veja&que&aqui&não&é&mais&necessário&definir&de&qual&classe&a&nossa&classe&herda,&a& definição&fica&apenas&na&interface.&&

Veja&que&o&código&também&faz&um&“#import”&para&o&arquivo&“.h”,&isso&é&para&que&o& arquivo&de&implementação&possa&ver&as&informações&definidas&na&interface,&como& variáveis&de&instância&e&também&receber&automaticamente&as&dependências&que& já&foram&importadas&no&mesmo.& Em&C&você&faria&o&mesmo&com&#include,&mas&o& #import&vai&um&pouco&mais&longe&e&evita&que&o&mesmo&arquivo&seja&“incluído” & duas&vezes,&um&problema&bem&comum & pra&quem&trabalha&com&C.&

Vamos&agora&começar&a&realmente&escrever&código:&

Listagem)3)– ) Conta.h )

#import <Cocoa/Cocoa.h>

@interface Conta : NSObject { float saldo;

}

-

(BOOL) depositar:(float)valor;

-

(float) saldo;

@end

Agora&a&nossa&classe&conta&tem&uma & variável&de&instância&definida&(do&tipo&

float ”), & declaramos&a&existência&do&método& depositar & que&recebe&um&parâmetro&

do&tipo&float && e&retorna&um& BOOL ,&o&boolean&da&linguagem.&Também&declaramos&o& método&“ saldo”&que&vai&ser&a&forma&de&acessar&a&variável&de& instância&“saldo”.&É&

possível&acessar&uma&variável&de&instância&de&uma&classe&em&Objective8 C& diretamente&de&“fora”&da&classe,&mas&o&melhor&é&fazer&o&acesso&sempre&via& métodos&(ou&as&propriedades&que&veremos&mais&a&frente).&

O&sinal&de&“ 8 “&(subtração)&antes& da&definição&do&método&avisa&que&esse&é&um& método&de&instância&(métodos&de&classe&são&definidos&com&um&sinal&de&adição,&o& “+”). & O&tipo&de&retorno&e&o&tipo&dos&parâmetros&recebidos&ficam&sempre&entre& parênteses. & &

Um&detalhe&importante&na&declaração&de&métodos&em&Objective8 C&é&que&o& parâmetro&fica&“dentro”&do&nome&do&método&e&não&após&a&definição&do&nome,&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

como&em&Java&ou&Ruby.& Como&o&método& depositar & recebe&um&parâmetro&é& necessário&colocar&os&“:”&para&separar&o&nome&do&parâmetro&que&está& sendo& passado,&depo is&vamos&entender&um&pouco&mais&como&se&nomeiam&métodos&em& Objective 8 C. &

Vejamos&então&como&vai&ficar&o&nosso&arquivo&“.m” :&

Listagem)4)– ) Conta.m )

#import "Conta.h"

@implementation Conta

-

}

-

}

(BOOL) depositar: (float) valor { if ( valor > 0 ) { saldo += valor; return YES; } else { return NO;

}

(float) saldo { return saldo;

@end

Olhando&pro&código&fonte&você&já&deve&ter&entendido&exatamente&o&que&ele&faz,&se& o&valor&passado&como&parâmetro&for&maior&do&que&zero,&ele&vai&somar&com&o& valor&atual&da&variável&de&instância&“ saldo”&e&retornar&YES,&que&é&um&atalho&para&o& valor&BOOL&que&representa&verdadeiro,&se&o&valor&passado&como&parâmetro&for& menor&ou&igual&a&zero&ele&simplesmente&retorna& NO. &

Assim&como&em&C,&blocos&de&código&em&Objective8 C&ficam&sempre&dentro&de&pares& de&chaves&(“{}”)&e&todas&as&estruturas&de&controle&que&você&conhece&do&C&(ou&Java& e&C#)&existem&exatamente&da&mesma&forma&em&Objective8 C. &

A&implementação&do&método&“ saldo”&é&ainda&mais&trivial,&ela&simpl esmente& retorna&o&valor&da&variável&de&instância&diretamente.&

Criando)o)nosso)primeiro)teste)unitário )

Com&a&nossa&classe&implementada,&agora&é&a&hora&de&escrever&um&teste&para&esse& primeiro&método&implementado. & A&primeira&coisa&a&se&fazer&é&criar&um&novo&

g rupo&dentro&do&projeto&pra&manter&as&classes&de&teste,&assim&podemos&

facilmente&separar&as&classes&dos&seus&testes&na&hora&de&gerar&a&aplicação&final,&já&

que&ela&não&precisa&levar&os&testes&consigo. & Clique&com&o&botão&direito&em& “AprendendoObjectivec”,&como&na&imagem&abaixo:&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)9)– ) Criando)o)grupo)“Test” )

&
&

Com&o&grupo&criado,&clique&com&o&botão&direito&em&“Test” ,&selecione&“Add”&e& “New&File”.&Você&vai&criar&uma&classe&de&teste&padrão&do&Cocoa,&como&na&imagem& abaixo: &

Imagem)10)– ) Criando)a)classe)de) testes)

&
&

Dê&o&nome&“ContaTest”&a&classe& e&selecione&o&Target&“Test”&apenas,&desmarcando& o&primeiro&Target&que&aparece,&como&na&imagem&abaixo:&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)11)– ) Selecionando)os)targets)da)classe)de)testes)

&
&

No&caso&dos&testes,&você&normalmente&não&precisa&definir& nada&no&arquivo&“.h”,&já& que&os&métodos&são&chamados&automaticamente,&então&vamos&nos&focar&apenas& no&arquivo&“.m”,&que&é&onde&nós&vamos&realmente&estar&trabalhando.&&

Implementando)o)nosso)primeiro)teste)

Listagem)5)– ) ContaTest.m )

#import "ContaTest.h" #import "Conta.h"

@implementation ContaTest

- (void) testDepositarComSucesso {

Conta * conta = [[Conta alloc] init]; [conta depositar:200]; STAssertTrue( [conta saldo] == 300, @"O saldo deve ser de 300 para que o teste falhe" );

}

@end

Assim&como&em&outros&frameworks&de&teste,&o&método&que&define&a& implementação&do&teste&precisa&ter&o&seu&nome&iniciando&com&“test”&e&não& retornar&nada&(por&isso&o&void).&Na&primeira&linha&do&teste&já&temos&vários& detalhes&da&linguagem&pra&entender.& &

A&primeira&coisa&a&ser&percebida&é&que&a&declaração&da&variável&contém&um&“*”,&se& você&vem&do&C,&sabe&que&isso&quer&dizer&que&essa&variável&é&na&verdade&uma& referencia&(ou&ponteiro)&pra&um&objeto&que&está&em&memória.&Sempre&que&você& define&uma&referencia&p ra&uma&variável&em&Objective8 C&é&necessário&colocar&o&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

“*”,&se&você&não&o&fizer&vai&receber&warnings&do&compilador&e&o&seu&programa&não& vai&funcionar&corretamente. &

Ainda&nessa&linha&temos&o&idioma&de&inicialização&de&objetos.&O&que&em&outras& linguagens&de&programação&OO&seria&feito&através&de&um&construtor,&em& Objective 8 C&se&faz&através&das&chamadas&a&“ alloc”,&um&método&de&classe&que& organiza&uma&nova&instância&do&objeto&em&memória&e&retorna&o&objeto&pronto& pra&uso , & e&“init”,&que&executa&finalmente&a&inicial ização&do&objeto.&É&possível& usar& também&o&método&de&classe&“ new”&em&vez&do&“par”&alloc/init&para&se&criar&um& objeto,&mas&é&preferível&usar&alloc/init,&especialmente&se&você&pretende&ter&várias& formas&de&inicializar&o&seu&objeto. &

Ótimo,&você&diz,&mas&o&que& diabos&são&aqueles& pares&de & colchetes& (“[]”)? &

Seguindo&a&tradição&de&Smalltalk,&em&Objective8 C&a&ideia&não&é&que&você&está& chamando&um&método&em&um&objeto,&mas&sim&enviando&uma&mensagem&a&ele.& Inicialmente,&a&sintaxe&pode&realmente&parecer&um&pouco&estranha,&mas&no&fim& das&contas&ela&é&bem&simples:&

[& objetoDestino& mensagem & ] &

Do&lado&esquerdo,&você&sempre&tem&o&objeto&para&o&qual&você&quer&enviar&a& mensagem,&do&lado&direito&você&tem&a&mensagem&que&está&sendo&enviada&(o& método&que&está&sendo&chamado),&tudo&isso&dentro&de&colchetes.&No&nosso&caso,& onde&fazemos&“ [[Conta alloc] init ]”,&estamos& enviando&a&mensagem&“ alloc”& para&o&objeto&que&representa&a&classe&“Conta”&e&no&valor&que&é&retornado&por&esse& método&(um&objeto&Conta)&fazemos&a&chamada&do&método&“ init ”.&O&idioma& alloc/init&é&comum&e&pervasivo&em&toda&a&linguagem&e&exemplos&de&código&que& você&vai&encontrar,&mas&evite&fazer&chamadas&de&método&dentro&de&chamadas&de& método&no&seu&código,&a&não&ser&que&seja&um&caso&muito&simples&como&esse&que& nós&estamos&vendo& aqui. &

Na&segunda&linha&do&teste&vemos&o&seguinte:&

[conta depositar:200];

Nós&enviamos&a&mensagem&“depositar”& para&o&objeto&representado&pela&variável&

“conta”&com&o&parâmetro&200.&Os&“:”&que&nós&usamos&na&definição&do&método&

“depositar”&fazem&realmente&parte&do&nome&do&método,&sendo&obrigatório&a&sua&

adição&a&chamada&(os&métodos&que&não&adicionam&“:”&são&os&que&não&recebem&

parâmetros).&

No&fim&temos&o&código&que&faz&a&asserção&do&teste:&

STAssertTrue( [conta saldo] == 300, @"O saldo deve ser de 300 para que o teste falhe" );

Comparamos&então&o&valor&do&saldo&com&300&exatamente&porque&queremos,&

nesse&primeiro&momento,&ver&o&teste&falhar.&STAssertTrue&não&é&um&método,&mas& uma&função&comum&que&você&definiria&como&uma&função&em&C,& ela&faz&parte&do& framework&de&testes&unitários&que&vem&por&padrão&dentro&do&Cocoa.&

Agora&um&detalhe&importante&que&pode&passar&desapercebido&é&a&definição&do&

texto&usado&como&mensagem&para&esse&teste,&em&vez&de&ser&somente&um&conjunto&

de&caracteres&entre&aspas,&há&um&“@”&antes&das&aspas.&Isso&quer&dizer&que&você&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

não&está&usando&uma&string&comum&do&C,&que&é&um&array&de&caracteres,&e&sim&um& objeto&do&tipo&NSString&que&adiciona&várias&funcionalidades&as&strings&comuns&do& C.&A&maior&parte&do&código&em&Objective8 C&que&lida&com&Strings&vai& esperar&que& você&envie&objetos&do&tipo&NSString,&então&é&bom&se&acostumar&a&escrever& primeiro&a&“@”&antes&de&declarar&um&string&no&seu&código. &

Voltemos&agora&para&o&Xcode,&onde&você&vai&mudar&o&Target&padrão&para&Test,&

veja&como&fazer&isso&na&imagem&abaixo:&

Imagem)12)– ) Alterando)o)Target)padrão)para)Test)

&
&

Agora&estamos&entrando&no&modo&de&testes&do&Xcode&vamos&poder&começar&a& executar&os&testes,&mas&antes&de&fazer&isso&precisamos&dizer&para&o&Target&“ Test ”& onde&ele&vai&achar&a&classe&Conta,&pois&ela&não&foi&adicionada&a&ele.&Pra&fazer&isso,& você&deve&selecionar&o&arquivo&“Conta.m”&e&arrastá 8 lo&para&dentro&da&pasta& “Compile&Sources”&do&Target&“Test”,&como&na&imagem&abaixo:&

Imagem)13)– ) Drag)e)drop)do)arquivo)“Conta.m”)em)Test)

&
&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Com&isso&feito,&podemos& finalmente&executar&o&build&do&projeto,&pra&fazer&isso& digite&“Command&+&B” .&Após&alguns&instantes&o&Xcode&deve&terminar&de&fazer&o& build&e&você&deve&ver&um&aviso&no&canto&inferior&direito&da&ferramenta&indicando& que&existem&dois&erros:&

Imagem)14)– ) Indicaç ão)de)erros)de)build)do)Xcode )

&
&

Ao&clicar&nos&erros&você&deve&ver&a&seguinte&tela:&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Imagem)15)– ) tela)de)erros)no)build)do)Xcode )

&
&

Como&você&pode&perceber,&o&erro&na&verdade&não&é&exatamente&no&build,&mas&sim&

no&nosso&teste&unitário&que&falhou,&já&que&o&valor&da&variável&não&é&300&e&sim&200.&

Para&ver&essa&tela&sem&ter&que&usar&o&mouse&pra&clicar&no&erro&basta&fazer&“Shift&+& Command&+&B”. & Agora&que&você&já&viu&a&tela,&troque&o&300&por&200&e&execute&o& build&mais&uma&vez&com&“Command&+&B” ,&o&seu&build&deve&executar&sem&erros,& agora&que&o&teste&já&está&implementado&corretamente.&

Vamos&agora&definir&os&métodos&sacar&e&transferir&na&classe&conta:&

Listagem)6)– ) Conta.h )

#import <Cocoa/Cocoa.h>

@interface Conta : NSObject { float saldo;

}

-

(BOOL) depositar: (float) valor;

-

(BOOL) sacar: (float) valor;

-

(BOOL) transferir: (float) valor para: (Conta *) destino;

-

(float) saldo;

@end

Estamos&quase&chegando&lá,& o&método&sacar&tem&a&definição&igual&a&depositar,& mas&o&método&“transferir:para:”&(veja&só&como&ele&se&chama)&deve&estar&dando& um&nó&no&seu&cérebro&nesse&momento.&Vejamos:&

- (BOOL) transferir: (float) valor para: (Conta *) destino;

Em&Objective8 C,&quando&você&tem&um&método&que& recebe&vários&parâmetros,& você&precisa&“dividir”&o&nome&do&método&em&pedaços&para&receber&os&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

parâmetros.&Então&em&vez&de&simplesmente&fazer&um&“transferir(&double&valor,& Conta&destino&)”,&como&você&faria&em&Java&ou&C#,&você&quebra&o&nome&do&método& e&transformar&ele&em&“transferir:& valor&para:&destino”.&&

Inicialmente&a&sintaxe&parece&estranha,&mas&a&própria&leitura&da&chamada&do& método&fica&mais&simples&e&se&você&tiver&um&método&que&recebe&vários& parâmetros&ele&com&certeza&vai&ficar&bem&mais&legível,&já&que&cada&parâmetro&va i& ter&o&s eu&identificador&antes.& &

Vejamos&agora&como&fica&a&implementação&desses&dois&métodos:&

Listagem)7)– ) Conta.m )

#import "Conta.h"

@implementation Conta

-

(BOOL) depositar: (float) valor { if ( valor > 0 ) { saldo += valor; return YES;

}

else { return NO;

}

}

-

(BOOL) sacar:(float)valor { if ( valor > 0 && valor <= saldo) { saldo -= valor; return YES;

}

else { return NO:

}

}

-

(BOOL) transferir:(float) valor para:(Conta *) destino { if ( [self sacar: valor]

 

&& [ destino depositar:

valor ] ){

return YES;

 

}

else { return NO;

}

}

-

(float) saldo { return saldo;

 

}

@end

 

A&essa&altura&do&campeonato,&você&já&sabe&exatamente&o&que&esse&código&todo&

está&fazendo,&então&vamos&passar&diretamente&pros&testes,&pra&ver&esses&novos&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

métodos&sendo&exercitados.&Em&todos&os&nossos&testes&vamos,&utilizar&um&objeto& conta,&então&em&vez&de&recriar&esse&objeto&a&cada&teste,&vamos&ser&inteligentes& definir&uma&variável&de&instância& Conta& no&nosso&teste&e&implementar&o&método& “setUp”&que&cria&a&conta&para&não&repetirmos&essa&operação:&

Listagem)8)– ) ContaTest.h )

#import <SenTestingKit/SenTestingKit.h>

@class Conta;

@interface ContaTest : SenTestCase { Conta * conta;

}

@end

Adicionamos&a&definição&da&variável&de&instância&na&classe,&como&esperado,&mas&o& que&é&esse&“@class”&que&também&está&aí? & O&@class&em&Objective8 C&é&uma& “forward&reference”&e&normalmente&é&utilizado&em&arquivos&“.h”&para&que&você& diga&que&o&seu&arquivo&depende&de&uma&classe&em&específico,&mas&não&vai&fazer&o& “#import”&dessa&classe&aqui,&vai&deixar&pra&importar&o&arquivo&da&classe&somente& no&seu&“.m” .&Se&você&não&colocar&o&@class&nem&o&“#import”&pra&o&arquivo&da& classe&não&vai&ser&possível&compilar&o&código. &

Um&detalhe&importante&do&“#import”&é&que&quando&o&texto&que&vem&após&ele&está&

entre&“<>”&(como&em& #import <SenTestingKit/SenTestingKit.h> ),&isso&

indica&ao&compilador&que&ele&deve&procurar&esse&arquivo&no&“load&path”&do&

sistema&operacional,&os&lugares&onde&ficam&os&arquivos&“.h”&do&mesmo.&Quando&o&

“#import”&aparece&usando&aspas&no&conteúdo&a&ser&importado,&quer&dizer&que&ele&

deve&procurar&dentro&dos&arquivos&locais&do&projeto&(como&em&#import

"Conta.h" ). &

Vejamos&agora&a&implementação&atual&dos&testes:&

Listagem))9)– ) ContaTest.m )

#import "ContaTest.h" #import "Conta.h"

@implementation ContaTest

-

(void) setUp { conta = [[Conta alloc] init]; [conta depositar: 200];

}

-

(void) testDepositarComSucesso {

[conta depositar:150]; STAssertTrue( conta.saldo == 350, @"Saldo final deve ser 350" );

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

}

-

(void) testDepositarComFalha {

[conta depositar:-150]; STAssertTrue( conta.saldo == 200, @"Valor do saldo não deve ter se modificado" );

}

- (void) testSacarComSucesso { [conta sacar:150]; STAssertTrue( conta.saldo == 50, @"O saldo atual deve ser 50" );

}

- (void) testSacarComValorMaior { [conta sacar: 250]; STAssertTrue( conta.saldo == 200, @"O saldo atual não deve ter se modificado" );

}

-

(void) testSacarComValorNegativo {

[conta sacar: -100]; STAssertTrue( conta.saldo == 200, @"O saldo atual não deve ter se modificado" );

}

-

(void) testTransferirComSucesso {

Conta * destino = [[Conta alloc] init];

[conta transferir:150 para: destino]; STAssertTrue( conta.saldo == 50, @"O saldo da conta origem deve ser 50" ); STAssertTrue( destino.saldo == 150, @"O saldo da conta destino deve ser 250" );

}

-

(void) testTransferirComFalha {

Conta * destino = [[Conta alloc] init];

[ conta transferir:250 para: destino ]; STAssertTrue( conta.saldo == 200, @"O saldo da conta origem deve ser 50" ); STAssertTrue( destino.saldo == 0, @"O saldo da conta destino deve ser 250" );

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

&

}

Maurício&Linhares &

@end

Temos&então&vários&testes&para&a&implementação&das&funcionalidades&da&nossa&

classe&conta,&eles&são&bem&simples,&mas&tem&duas&coisas&importantes&que&não&

discutimos&ainda,&a&primeira&é&essa:&

conta.saldo == 200

Antes,&no&nosso&teste,&fazíamos&a&chamada&assim:&

[conta saldo] == 200

Em&Objective8 C,&se&você&tem&um&método&que&não&recebe&parâmetros&e&retorna& um&valor,&esse&método&pode&ser&chamado&como&se&ele&fosse&uma&propriedade&do& seu&objeto,&sem&que&você&tenha&que& fazer&uma&invocação&explícita&do&mesmo,& então&“conta.saldo”&é&a&mesma&coisa&que&escrever&“[conta&saldo]”,&o&compilador& vai&fazer&a&mágica&de&transformar&o&primeiro&no&segundo&pra&você.&

Já&o&segundo&caso:&

[ conta transferir:250 para: destino ]

Aqui&nós&vemos&um&exemplo&da&chama da&do&método&“transferir:para:”,&junto& com&o&transferir&nós&temos&o&valor&que&vai&ser&transferido&e&logo&depois&de&para& temos&o&objeto&que&vai&receber&a&transferência,&veja&que&não&existem&vírgulas& separando&os&parâmetros,&eles&são&separados&normalmente&pelos&espaços&entre& os&nomes&que&formam&o&método&e&os&parâmetros&passados. &

Criando)um)“construtor”)para)o)nosso)objeto)conta )

Como&já&comentamos&antes,& o&par&“[[Conta&alloc]&init]”&serve&pra&criar&o&objeto&e& inicializá8 lo&dentro&do&projeto,&mas&e&se&nós&quisermos& definir&uma&forma& personalizada?&Simples,&criamos&um&método&de&inicialização.&No&nosso&caso& queremos&poder&criar&contas&com&um&saldo&que&seja&diferente&de&zero.& Começamos&por&definir&o&método&“initWithSaldo”&em&“Conta.h”:&

Listagem)10) – ) Conta.h) – ) declarando)o)método)initWithSaldo)

#import <Cocoa/Cocoa.h>

@interface Conta : NSObject { float saldo;

}

-

(Conta *) initWithSaldo: (float) valor;

-

(BOOL) depositar: (float) valor;

-

(BOOL) sacar: (float) valor;

-

(BOOL) transferir: (float) valor para: (Conta *) destino;

-

(float) saldo;

@end

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Como&não&existem&construtores&realmente&dentro&da&linguagem,&o&que&nós&

fazemos&é&definir&métodos&que&inicializem&o&objeto&com&o&valor&que&nos&

interessa,&vejamos&a&implementação&agora&pra&entender&um&pouco&mais&o&que&

está&acontecendo&e&porque&é&necessário&criar&esses&métodos:&

Listagem)11)– ) Conta.m) )

#import "Conta.h"

@implementation Conta

- (Conta *) initWithSaldo:(float)valor { if ( self = [ self init]) { saldo = valor;

}

return self;

}

// todo aquele código que você já viu

@end

Mais&um&caso&de&idioma&da&linguagem&surge&então&pra&nós&nesse&momento:&

if ( self = [ self init]) {

Por&mais&estranho&que&pareça,&esse&código&está&realmente&atribuindo&um&valor&a&

variável&“self”&(“self”&é&equivalente&ao&“this”&em&Java&e&C#,&é&uma&referência&para&

o&objeto&onde&o&método&em&execução&atual&foi&chamado)&dentro&do&seu&objeto.&&

Mas&porque&al guém&iria&querer&fazer&isso?

Na&implementação&da&Apple&do&Objective8

“class 8 clusters”.&Quando&você&cria&um&objeto&do&tipo&NSString,&o&que&você&recebe& pode&não&ser&exatamente&um&NSString,&mas&uma&subclasse&dele.&As&classes&que& nós&vemos&“do&lado&de&fora”&funcionam&apenas&como&um&meio&pra&se&acessar&as& classes&que&fazem&realmente&o&trabalho,&mas&esses&detalhes&de&implementação& ficam&escondidos&graças&a&essa&pequena&mágica&do&método&init&(atribuir&um&novo& valor&a&self&e&retornar&esse&valor).&

No&caso&da&nossa&classe&não&seria&necessário&fazer&essa&mágica,&já&que&estamos& realmente&retornando&uma&conta,&mas&o&ideal&é&que&você&construa&todos&os&seus& inicializadores&dessa&forma&para&que&quando&for&criar&uma&subclasse&de&uma& classe&padrã o&da&linguagem&não&se&esquecer&e&terminar&com&bugs&estranhos&no& seu&código. &

Outra&coisa&importante&também&é&lembrar8 se&de&chamar&o&método&“ init ”&da&sua& classe,&se&você&estiver&implementando&um&novo&inicializador&(como&nós&fazemos& nesse&código)&ou&chamar&o& método& init & da&sua&superclasse&(com&[super&init])&se& você&estiver&sobrescrevendo&o&método&“ init ” ,&assim&você&não&perde&o&código&de& inicialização&que&já&tenha&sido&implementado&na&classe&atual&e&nas&suas& superclasses.&

Definindo)propriedades)automaticamente) nos)objetos )

Nós&vimos&que&o&compilador&é&inteligente&o&suficiente&pra&aceitar&que& “[conta& saldo]”&seja&chamado&como&“ conta.saldo”,&mas&além&disso&nós&também&podemos&

&

C&existe&um&conceito&chamado&de&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

instruir&o&compilador&para&que&ele&gere&os&métodos&de&acesso&para&as& propriedades&dos&nossos&objetos&automaticamente&(pense&no&“generate&getters& and&setters”&do&Eclipse&ou&attr_accessor&em&Ruby).&Pra&isso,&vamos&definir&novas& propriedades&na&nossa&classe,&“agencia”&e& & “conta”.&Vejamos&como&fica&o& nosso& “Conta.h”&agora: &

Listagem)12) – ) Conta.h)com)as)novas)propriedades)definidas )

#import <Cocoa/Cocoa.h>

@interface Conta : NSObject { float saldo; NSString * conta; NSString * agencia;

}

@property (copy, nonatomic) NSString * conta; @property (copy, nonatomic) NSString * agencia; @property (readonly) float saldo;

- (Conta *) initWithSaldo: (float) valor;

- (BOOL) depositar: (float) valor;

- (BOOL) sacar: (float) valor;

- (BOOL) transferir: (float) valor para: (Conta *) destino;

@end

Nós&definimos&as& duas&variáveis&de&instância,&“agencia”&e&“conta”,&e&logo&depois& temos&as&declarações&das&propriedades,&com&“@property”:&

@property (copy, nonatomic) NSString * conta;

Isso&indica&ao&compilador&que&nós&vamos&ter&os&métodos&abaixo&definidos:&

8

(NSString&*&)&co nta; &

8

(void)&setConta:&(&NSString&*&); &

As&instruções&“copy”&e&“nonatomic”&são&atributos&que&vão&ser&utilizados&na&

geração&da&implementação&dos&métodos.&&

8

“copy”&indica&que&quando&um&objeto&for&recebido&como&parâmetro,&deve& ser&criada&uma&cópia&desse&objeto&e& essa&cópia&é&quem&vai&ser&atribuída&a& variável&de&instância,&isso&é&necessário&especialmente&se&você&está& recebendo&dados&da&interface,&pois&os&strings&que&vem&dela&podem&ser& recolhidos&da&memória&a&qualquer&momento&nos&ambientes&onde&não&há& coletor&de&lixo,&como&iPads&e&iPhones.&

8

“nonatomic”&indica&que&os&métodos&gerados&não&vão&fazer&nenhum& controle&sobre&o&acesso&de&forma&concorrente.&Esse&normalmente&é&o&caso& pra&maior&parte&das&aplicações,&mas&se&você&vai&utilizar&esse&objeto&em&um& ambiente&com&concorrência,&onde&várias&threads&vão&acessar&o&mesmo& objeto&e&chamar&seus&métodos,&deve&remover&isso.&

8

“readonly”&indica&que&apenas&o&método&“getter”,&que&lê&o&valor&da&variável,& vai&ser&gerado,&o&método&set,&que&altera&o&valor&da&variável&não&vai&ser& gerado.&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Com & os&métodos&definidos,&agora&voltamos&pra&“Conta.m”&pra&declarar&o&código& que&vai&fazer&com&que&os&métodos&sejam&realmente&gerados,&vejamos&como&fica&o& código&agora: &

Listagem)13)– ) Conta.m)com)a)definição)das)propriedades)e)gerenciamento)de) memória)

#import "Conta.h"

@implementation Conta

@synthesize agencia, conta, saldo;

- (void) dealloc {

[

self.agencia release ];

[

self.conta release ];

[

super dealloc ];

}

// todo o resto do código que você já conhece aqui

@end

A&mágica&de&verdade&vive&no&“@synthesize”,&ele&instrui&o&compilador&a&ler&as& informações&das&propriedades&definidas&através&de&“@property”&e&gerar&os& métodos.&Junto&com&isso&chegamos&a&um&detalhe&importante&da&programação& com&Objective8 C,&especialmente&se& você&estiver&planejando&programar&para&iOS,&o& gerenciamento&de&memória. &

Com&a&definição&das&propriedades&nós&definimos&também&o&método&“dealloc”&que& é&chamado&quando&um&objeto&vai&ser&removido&da&memória,&para&que&ele&possa& limpar&da&memória&também&os&objetos&para&os&quais&ele&aponta.&Quando&você& está&programando&em&Objective8 C&para&iOS,&não&existe&um&coletor&de&lixo& automático,&liberar&a&memória&é&responsabilidade&do&programador,&então&é& necessário&que&você&tome&cuidado&para&não&vazar&memória&no&seu&código& e& estourar&a&memória&do&dispositivo.&

Em&Objective8 C&o&controle&de&memória,&quando&não&é&feito&através&do&coletor&de& lixo,&acontece& através&da&contagem&de&referencias.&Sempre&que&você&cria&um& objeto&usando&“alloc”&ou&“new”&esse&objeto&fica&com&o&contador&de&referencias&em&

1&(um),&cada&vez&que&você&chama&“retain”&no&objeto&(como&em&“[objeto&retain]”)&

esse&contador&aumenta&em&um&e&cada&vês&que&você&chama&“release”&(como&em&

“[objeto&release]”)&o&contador&diminui&em&1.&Quando&o&contador&de&referencias&

atingir&0 ,&o&objeto&é&removido&da&memória.&

No&nosso&caso,&as&propriedades&“conta”&e&“agencia”&são&definidas&como&“copy”,& isso&quer&dizer&que&o&objeto& que&vai&ser&colocado&na&variável&de&instância&vai&ser& clonado&e&o&clone&é&o&objeto&que&vai&finalmente&ficar&disponível&para&a&nossa& classe.&Como&o&clone&é&um&objeto&recém8 criado&com&base&em&outro&objeto&a&sua&

contagem&de&referencias&é&1&(um),&o&que&quer&dizer&que&quando&chamarmos&

“release”&neles,&eles&vão&ser&removidos&da&memória.&

Pra&limpar&a&memória&que&estamos&usando,&precisamos& ajustar&o&nosso&teste& para&fazer&o&“release”&dos&objetos&conta&que&estão&sendo&criados.&Vamos&fazer&o&

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

release&da&variável&de&instância&conta&no&método&tearDown&e&da&conta&destino&

em&cada&um&dos&testes,&vejamos&o&que&muda&na&nossa&classe&teste:&

Listagem)14)– ) ContaTest.m)com)o)código)de)gerenciamento)de)memória )

@implementation ContaTest

//métodos não mostrados aqui não foram alterados

-

(void) tearDown {

[

conta release ];

}

-

(void) testTransferirComSucesso {

Conta * destino = [[Conta alloc] initWithSaldo: 100 ];

[conta transferir:150 para: destino]; STAssertTrue( conta.saldo == 50, @"O saldo da conta origem deve ser 50" ); STAssertTrue( destino.saldo == 250, @"O saldo da conta destino deve ser 250" );

[ destino release ];

}

-

(void) testTransferirComFalha {

Conta * destino = [[Conta alloc] init];

[ conta transferir:250 para: destino ];

STAssertTrue( conta.saldo == 200, @"O saldo da conta origem deve ser 50" ); STAssertTrue( destino.saldo == 0, @"O saldo da conta destino deve ser 250" );

[ destino release ];

}

-

(void) testSetContaEAgencia { conta.agencia = @"1111-0"; conta.conta = @"10.000-9";

STAssertEqualObjects( conta.agencia, @"1111-0", @"O valor deve ser igual" ); STAssertEqualObjects( conta.conta, @"10.000-9", @"O valor deve ser igual" );

}

@end

Curso&de&desenvolvimento&de&aplicações&para&iOS& usando&Objective8 C&

Maurício&Linhares &

&

Adicionamos&a&nossa&implementação&o&método&“tearDown”&que&envia&um& “release”&para&o&objeto&conta&e&também&fazemos&o&release&dos&objetos&destino& criados&nos&testes&de&transferência.&Você&nunca&deve&chamar&o&método&dealloc& diretamente&nos&seus&objetos,&sempre&chame&release&e&deixe&que&o&próprio& runtime&do&Objective8 C&vai&fazer&a&chamada&a&dealloc&quando&for&a&hora&correta.&

É&possível&definir&algumas&regrinhas&básicas&na&hora&de&lidar&com&a&gerência&de& memória&em&aplicações&escritas&em&Objective8 C:&

Se&você&pegou&um&objeto&através&de&“alloc/new/copy”,&esse&objeto&tem&

um&contador&de&1&e&você&deve&se&lembrar&de&liberar&esse&objeto&quando&

ele&não&for&mais&necessário;&

Se&você&pegou&um&objeto&de&outro&lugar,&assuma&que&ele&tem&um&contador& de&1,&se&você&só&vai&usá8 lo&e&deixar&ele&pra&lá,&não&faça&nada&com&ele,&quem& passou&ele&pra&você&provavelmente&vai&limpá 8 lo&quando&for& necessário.&&

Se&você&precisa&manter&um&objeto&recebido&de&outro&lugar&para&usá 8 lo&em& outro&momento,&chame&“retain”&nele&para&que&o&contador&aumente&para&

“2”,&assim&quando&quem&lhe&passou&esse&objeto&chamar&“release”&nele&o&

contador&vai&baixar&pra&“1”&e&o& objeto&ainda&não&vai&ser&liberado&da& memória.& &

Sempre&que&você&dá&“retain”&em&um&objeto,&deve&garantir&que&vai&dar&um& “release”&nele&em&algum&momento,&se&você&não&der&o&“release”,&com& certeza&vai&estar&vazando&memória&na&sua&aplicação;&

Gerenciamento&de& memória&é&um&tópico&longo&e&vamos&nos&aprofundar&mais&nele& conforme&avançamos&para&a&construção&das&nossas&aplicações&para&iOS,&essa& introdução&é&apenas&para&que&você&entenda&o&básico&de&como&esse&conceito& funciona&dentro&da&linguagem. &