Вы находитесь на странице: 1из 27

Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C

Nauiicio Linhaies

1
Desenvo|vendo ap||caes para |CS usando Cb[ect|ve-C
Nauiicio Linhaies mauiicio.linhaiesgmail.com
!"#"$%&'%()"$*& !" ,-'(.,/0"# -,1, (&# 2#,$!& &34".*(%"5. 6
($*1&!2/7& 8
.,-9*2'& 6 5 .&$:"."$!& &34".*(%"5. ;
INAuEN 1 - SELE0 BE PR0}ET0S N0 XC0BE S
INAuEN 2 - CRIANB0 0 PR0}ET0 N0 XC0BE 4
INAuEN S - vIS0ALIZA0 INICIAL B0 PR0}ET0 S
INAuEN 4 - CRIANB0 0 TARuET Q0E vAI R0BAR 0S N0SS0S TESTES 6
INAuEN S - ABICI0NANB0 0 EXEC0TAvEL BA APLICA0 C0N0 BEPENBNCIA A0 TARuET TEST 7
INAuEN 6 - CRIANB0 A N0SSA PRINEIRA CLASSE EN 0B}ECTIvE-C 8
INAuEN 7 - CRIANB0 A N0SSA PRINEIRA CLASSE EN 0B}ECTIvE-C 9
INAuEN 8 - vIS0ALIZA0 B0 NAvEuAB0R BE ARQ0Iv0S C0N A CLASSE C0NTA CRIABA. 9
LISTAuEN 1 - C0NTA.B 9
LISTAuEN 2 - C0NTA.N 11
LISTAuEN S - C0NTA.B 11
LISTAuEN 4 - C0NTA.N 12
.1(,$!& & $&##& -1()"(1& *"#*" 2$(*<1(& 68
INAuEN 9 - CRIANB0 0 uR0P0 "TEST" 1S
INAuEN 1u - CRIANB0 A CLASSE BE TESTES 1S
INAuEN 11 - SELECI0NANB0 0S TARuETS BA CLASSE BE TESTES 14
()-'")"$*,$!& & $&##& -1()"(1& *"#*" 6=
LISTAuEN S - C0NTATEST.N 14
INAuEN 12 - ALTERANB0 0 TARuET PABR0 PARA TEST 16
INAuEN 1S - BRAu E BR0P B0 ARQ0Iv0 "C0NTA.N" EN TEST 16
INAuEN 14 - INBICA0 BE ERR0S BE B0ILB B0 XC0BE 17
INAuEN 1S - TELA BE ERR0S N0 B0ILB B0 XC0BE 18
LISTAuEN 6 - C0NTA.B 18
LISTAuEN 7 - C0NTA.N 19
LISTAuEN 8 - C0NTATEST.B 2u
LISTAuEN 9 - C0NTATEST.N 2u
.1(,$!& 2) >.&$#*12*&1? -,1, & $&##& &34"*& .&$*, 88
LISTAuEN 1u - C0NTA.B - BECLARANB0 0 NET0B0 INITWITBSALB0 22
LISTAuEN 11 - C0NTA.N 2S
!"@($($!& -1&-1("!,!"# ,2*&),*(.,)"$*" $&# &34"*&# 8;
'(#*,A") 68 B .&$*,C: .&) ,# $&%,# -1&-1("!,!"# !"@($(!,# 8=
LISTAuEN 1S - C0NTA.N C0N A BEFINI0 BAS PR0PRIEBABES E uERENCIANENT0 BE NEN0RIA 2S
LISTAuEN 14 - C0NTATEST.N C0N 0 C0BIu0 BE uERENCIANENT0 BE NEN0RIA 26


Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

2
Introduo
Este mateiial tem como objetivo seivii ue iefeincia paia o cuiso ue
uesenvolvimento ue aplicaes usanuo 0bjective-C e XCoue paia i0S, o sistema
opeiacional paia uispositivos moveis ua Apple, como iPhones, iPous e iPaus. Ele
faz paite uo mateiial complementai paia as aulas expositivas uo cuiso ue
uesenvolvimento paia i0S.
Paia seguii esse mateiial voc piecisa ue um computauoi com Nac0S e XCoue
instalauos, alm uo SBK paia uesenvolvimento ue aplicaes paia i0S. 0 mateiial
tambm assume que voc j tem expeiincia com o uesenvolvimento ue
softwaie em ao menos uma linguagem oiientaua a objetos.
Conceitos bsicos ue piogiamao oiientaua a objetos como vaiiveis ue
instncia, mtouos, constiutoies, heiana, encapsulamento no vo sei
explicauos, assume-se que quem est lenuo o mateiial j tem conhecimento ue
touos esses conceitos que so lugai comum em qualquei linguagem ue
piogiamao oiientaua a objetos.
Em viias paites uo mateiial voc vai encontiai a fala "Abia o menu contextual
uo item X" ou "clique com o boto uiieito em X", isso quei uizei usai o boto
uiieito uo mouse (em um mouse comom) fazei "Contiol + Click" no item
selecionauo ou, se voc estivei usanuo um tiackpau multi-touch, clicai com os
uois ueuos ao mesmo tempo.

Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

S
Cap|tu|o 1 - Conhecendo Cb[ect|ve-C
0 couigo fonte ueste piimeiio capitulo est uisponivel em -
https:github.commauiiciocapitulo-1-cuiso-ios
0bjective-C uma linguagem ue piogiamao oiientaua a objetos ue uso geial e
a lingua pauio paia o uesenvolvimento ue aplicaes paia o Nac 0S e hoje
tambm paia o i0S, ambos sistemas opeiacionais uesenvolviuos pela Apple. A
linguagem ueiivaua uiietamente uo C, com algumas caiacteiisticas ue
Smalltalk, como o uso ue paimetios uentio uo nome uo mtouo em vez ue em
uma seo ue paimetios no mesmo.
vamos fazei agoia uai os nossos piimeiios passos com o XCoue, ciianuo um
piojeto. Abia o XCoue, essa ueve sei a piimeiia janela que voc vai vei:
Imagem 1 - Se|eo de pro[etos no kCode

Nessa pgina, selecione "Cieate a new Xcoue pioject", aqui est a pioxima janela
que voc vai vei:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

4
Imagem 2 - Cr|ando o pro[eto no kcode

Nesse piimeiio momento, vamos iniciai com uma aplicao paia Nac0S, pia
entenuei o funcionamento ua linguagem e nos acostumaimos com o Xcoue como
feiiamenta. Apos selecionai "Nac 0S X" -> "Application" -> "Commanu Line
Tool", alm ue selecionai "Founuation" no campo ue seleo. B o nome
"Apienuenuo0bjectivec" ao piojeto.
Com o piojeto ciiauo, voc ueve vei uma janela como essa agoia:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

S
Imagem 3 - V|sua||zao |n|c|a| do pro[eto

0m fatoi inteiessante ao se iniciai o uesenvolvimento usanuo Xcoue que
mesmo se paiecenuo com pastas, "Souice", "Bocumentation", "Exteinal
fiamewoiks anu libiaiies" e "Piouucts" no so pastas, mas "agiupamentos" ue
conteuo. Se voc foi at a pasta que est o piojeto, vai peicebei que no
existem uiietoiios equivalentes a eles, isso acontece poique o Xcoue oiganiza os
aiquivos apenas logicamente e no fisicamente uentio uo piojeto.
Com o nosso piojeto ciiauo, vamos ciiai um taiget paia os testes unitiios que
vamos escievei uuiante o exemplo. Pia fazei isso, clique com o boto uiieito ou
"Contiol + Click" no maicauoi "Taigets", siga paia "Auu", uepois "New Taiget".
voc ueve vei a tela abaixo:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

6
Imagem 4 - Cr|ando o target que va| rodar os nossos testes

Ao paitii pia pioxima tela voc vai uefinii o nome uo taiget, coloque o nome
Test. Assim que o taiget foi ciiauo, ele vai abiii a janela ue opes uo mesmo,
nela, selecione a aba "ueneial", clique no boto "+", voc ueve vei ento uma
janela como a imagem logo abaixo, selecione "Apienuenuo0bjectivec" e clique
em "Auu Taiget".
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

7
Imagem S - Ad|c|onando o executve| da ap||cao como dependnc|a ao target
1est

Estamos agoia finalmente piontos pia comeai a escievei o couigo uo piojeto.
Paia entenuei as constiues bsicas ua linguagem, vamos ciiai uma classe
Conta que guaiue os uauos ue agncia, nmeio ue conta, banco e saluo. Alm
uisso a classe tambm vai contei os mtouos paia sacai, uepositai e tiansfeiii
uinheiio entie contas.
Selecione o giupo "Souice" e abia o menu contextual. v em "Auu" -> "New File".
Selecione "Cocoa Class" e uepois "0bjective-C class", como na imagem abaixo:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

8
Imagem 6 - Cr|ando a nossa pr|me|ra c|asse em Cb[ect|ve-C

Na pioxima janela, coloque o nome ua classe como senuo "Conta.m" e maique o
checkbox "Also cieate 'Conta.h'":
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

9
Imagem 7 - Cr|ando a nossa pr|me|ra c|asse em Cb[ect|ve-C

Com a classe ciiaua, voc ueve vei os aiquivos no Xcoue como na imagem abaixo:
Imagem 8 - v|sua||zao do navegador de arqu|vos com a c|asse Conta cr|ada.

0lhanuo pia essa imagem pouemos vei que existe um aiquivo "Conta.m" e um
aiquivo "Conta.h", vejamos o que h ue couigo em caua um uesses aiquivos:
L|stagem 1 - Conta.h
#import <Cocoa/Cocoa.h>

@interface Conta : NSObject {

}

@end
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

1u
Se voc nunca piogiamou em C na viua, ueve estai se peiguntanuo poique temos
uois aiquivos paia uma nica classe, um ".h" e outio ".m". 0 aiquivo ".h",
funciona como "cabealho" (uai o ".h", ue "heauei"), nele voc uefine a inteiface
pblica ua classe, como os atiibutos que ela tem e os mtouos que ela
implementa (e que uevem ficai visiveis paia teiceiios).
Em 0bjective-C, uifeientemente ue }ava e outias linguagens, no existem
mouificauoies ue nivel ue visibiliuaue paia as classes ou os seus membios (como
mtouos e atiibutos), tuuo "visivel", mas apenas o que estivei uefiniuo no
aiquivo ".h" fica iealmente uisponivel paia outios objetos que queiiam usai a
sua classe.
0lhanuo agoia uiietamente paia o couigo fonte, vemos o "!"#$%&'
)*%+%,-*%+%,./012 isso quei uizei que a nossa classe est ueclaianuo que vai
utilizai funcionaliuaues uo fiamewoik "!"#"$" (na veiuaue nos so piecisamos
uo fiamewoik "%"&'($)*"'", mas vamos ueixai assim poi enquanto). Logo apos
isso vemos o seguinte couigo:
3"4'5&6,+5 *%4', 7 89:;<5+'
Sempie que voc vii um caiacteie "" (aiioba) em couigo esciito em 0bjective-
C, quei uizei que o que vem logo apos ele uma extenso ua linguagem ao C.
0pa, peiai, como assim uma "extenso a linguagem C".
0bjective-C, assim como C++, existe como uma extenso a linguagem C. voc
poue escievei couigo C uentio ue piogiamas esciitos em 0bjective-C e o seu
couigo (teoiicamente) vai compilai e funcionai noimalmente. 0s uesigneis ua
linguagem iesolveiam ento uefinii uma foima ue ueixai claio o que no "C
puio" na linguagem usanuo o caiactei "". Ento sempie que voc vii o "" j
sabe que isso uma extenso uo 0bjective-C paia auicionai novos
compoitamentos ao nosso queiiuo e amauo C.
A extenso 3"4'5&6,+5 uiz que estamos uefininuo uma nova classe na linguagem
e o que segue essa ueclaiao o nome ua classe, no nosso caso "*%4',". Logo
apos a ueclaiao uo nome ua classe o ": 89:;<5+'" uiz que a nossa classe "*%4',"
heiua ue "89:;<5+'". Bifeientemente ue outias linguagens onue existe uma nica
classe iaiz e me ue touos os objetos (pense no 0bject ue }ava, Ruby, C e tantas
outias), em 0bjective-C voc mesmo poue uefinii uma classe iaiz, mas
noimalmente voc vai heiuai ue "89:;<5+'" que a classe iaiz uo fiamewoik
base ue 0bjective-C utilizauo no uesenvolvimento ue aplicaes paia o Nac 0S e
i0S. 0bviamente, se voc no uissei ue qual classe voc heiua, a sua classe se
toina automaticamente uma classe iaiz, ento lembie-se sempie ue uefinii a
supeiclasse ua sua classe ou simplesmente coloque que ela heiua ue "89:;<5+'".
0 pai ue chaves "" que vem logo apos a ueclaiao ua classe o lugai onue
voc uefine as vaiiveis ue instncia ua sua classe e somente elas (no, no
aqui que voc coloca os mtouos). Touas as vaiiveis ue instncia piecisam estai
uefiniuas aqui no aiquivo ".h", mesmo aquelas que voc queiia ueixai como
"piivauas".
Apos o pai ue chaves vem o coipo ua classe, que o lugai onue voc uefine os
mtouos que essa classe implementa (mas voc no os implementa aqui, voc
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

11
apenas uefine quais so eles). No uefinii um mtouo aqui noimalmente faz com
que no seja possivel pia que algum o invoque, uma uas foimas ue se ciiai
mtouos "piivauos" em 0bjective-C, j que no existe esse conceito uentio ua
linguagem em si.
L|stagem 2 - Conta.m
#import "Conta.h"

@implementation Conta

@end
No aiquivo ".m" voc encontia agoia o couigo ieal ua classe (mesmo que no
tenhamos colocauo naua ainua nele. Enquanto que no aiquivo ".h" nos haviamos
uefiniuo a 3"4'5&6,+5 uo couigo, agoia estamos uefininuo a 3"#$=5#54','"%4.
veja que aqui no mais necessiio uefinii ue qual classe a nossa classe heiua, a
uefinio fica apenas na inteiface.
veja que o couigo tambm faz um "impoit" paia o aiquivo ".h", isso paia que o
aiquivo ue implementao possa vei as infoimaes uefiniuas na inteiface, como
vaiiveis ue instncia e tambm iecebei automaticamente as uepenuncias que
j foiam impoitauas no mesmo. Em C voc faiia o mesmo com incluue, mas o
impoit vai um pouco mais longe e evita que o mesmo aiquivo seja "incluiuo"
uuas vezes, um pioblema bem comum pia quem tiabalha com C.
vamos agoia comeai a iealmente escievei couigo:
L|stagem 3 - Conta.h
#import <Cocoa/Cocoa.h>

@interface Conta : NSObject {
float saldo;
}
- (BOOL) depositar:(float)valor;
- (float) saldo;
@end
Agoia a nossa classe conta tem uma vaiivel ue instncia uefiniua (uo tipo
"6=%,'"), ueclaiamos a existncia uo mtouo >5$%?"',& que iecebe um paimetio
uo tipo 6=%,' e ietoina um @::A, o boolean ua linguagem. Tambm ueclaiamos o
mtouo "?,=>%" que vai sei a foima ue acessai a vaiivel ue instncia "saluo". E
possivel acessai uma vaiivel ue instncia ue uma classe em 0bjective-C
uiietamente ue "foia" ua classe, mas o melhoi fazei o acesso sempie via
mtouos (ou as piopiieuaues que veiemos mais a fiente).
0 sinal ue "-" (subtiao) antes ua uefinio uo mtouo avisa que esse um
mtouo ue instncia (mtouos ue classe so uefiniuos com um sinal ue auio, o
"+"). 0 tipo ue ietoino e o tipo uos paimetios iecebiuos ficam sempie entie
painteses.
0m uetalhe impoitante na ueclaiao ue mtouos em 0bjective-C que o
paimetio fica "uentio" uo nome uo mtouo e no apos a uefinio uo nome,
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

12
como em }ava ou Ruby. Como o mtouo >5$%?"',& iecebe um paimetio
necessiio colocai os ":" paia sepaiai o nome uo paimetio que est senuo
passauo, uepois vamos entenuei um pouco mais como se nomeiam mtouos em
0bjective-C.
vejamos ento como vai ficai o nosso aiquivo ".m":
L|stagem 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
0lhanuo pio couigo fonte voc j ueve tei entenuiuo exatamente o que ele faz, se
o valoi passauo como paimetio foi maioi uo que zeio, ele vai somai com o
valoi atual ua vaiivel ue instncia "?,=>%" e ietoinai BC9, que um atalho paia o
valoi B00L que iepiesenta veiuaueiio, se o valoi passauo como paimetio foi
menoi ou igual a zeio ele simplesmente ietoina 8:.
Assim como em C, blocos ue couigo em 0bjective-C ficam sempie uentio ue paies
ue chaves ("") e touas as estiutuias ue contiole que voc conhece uo C (ou }ava
e C) existem exatamente ua mesma foima em 0bjective-C.
A implementao uo mtouo "?,=>%" ainua mais tiivial, ela simplesmente
ietoina o valoi ua vaiivel ue instncia uiietamente.
Cr|ando o nosso pr|me|ro teste un|tr|o
Com a nossa classe implementaua, agoia a hoia ue escievei um teste paia esse
piimeiio mtouo implementauo. A piimeiia coisa a se fazei ciiai um novo
giupo uentio uo piojeto pia mantei as classes ue teste, assim pouemos
facilmente sepaiai as classes uos seus testes na hoia ue geiai a aplicao final, j
que ela no piecisa levai os testes consigo. Clique com o boto uiieito em
"Apienuenuo0bjectivec", como na imagem abaixo:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

1S
Imagem 9 - Cr|ando o grupo "1est"

Com o giupo ciiauo, clique com o boto uiieito em "Test", selecione "Auu" e
"New File". voc vai ciiai uma classe ue teste pauio uo Cocoa, como na imagem
abaixo:
Imagem 10 - Cr|ando a c|asse de testes

B o nome "ContaTest" a classe e selecione o Taiget "Test" apenas, uesmaicanuo
o piimeiio Taiget que apaiece, como na imagem abaixo:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

14
Imagem 11 - Se|ec|onando os targets da c|asse de testes

No caso uos testes, voc noimalmente no piecisa uefinii naua no aiquivo ".h", j
que os mtouos so chamauos automaticamente, ento vamos nos focai apenas
no aiquivo ".m", que onue nos vamos iealmente estai tiabalhanuo.
Imp|ementando o nosso pr|me|ro teste
L|stagem S - Conta1est.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 outios fiamewoiks ue teste, o mtouo que uefine a
implementao uo teste piecisa tei o seu nome inicianuo com "test" e no
ietoinai naua (poi isso o D%">). Na piimeiia linha uo teste j temos viios
uetalhes ua linguagem pia entenuei.
A piimeiia coisa a sei peicebiua que a ueclaiao ua vaiivel contm um "", se
voc vem uo C, sabe que isso quei uizei que essa vaiivel na veiuaue uma
iefeiencia (ou ponteiio) pia um objeto que est em memoiia. Sempie que voc
uefine uma iefeiencia pia uma vaiivel em 0bjective-C necessiio colocai o
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

1S
"", se voc no o fizei vai iecebei wainings uo compilauoi e o seu piogiama no
vai funcionai coiietamente.
Ainua nessa linha temos o iuioma ue inicializao ue objetos. 0 que em outias
linguagens ue piogiamao 00 seiia feito atiavs ue um constiutoi, em
0bjective-C se faz atiavs uas chamauas a ",==%+", um mtouo ue classe que
oiganiza uma nova instncia uo objeto em memoiia e ietoina o objeto pionto
pia uso, e "init", que executa finalmente a inicializao uo objeto. E possivel usai
tambm o mtouo ue classe "45E" em vez uo "pai" allocinit paia se ciiai um
objeto, mas piefeiivel usai allocinit, especialmente se voc pietenue tei viias
foimas ue inicializai o seu objeto.
0timo, voc uiz, mas o que uiabos so aqueles paies ue colchetes ("").
Seguinuo a tiauio ue Smalltalk, em 0bjective-C a iueia no que voc est
chamanuo um mtouo em um objeto, mas sim envianuo uma mensagem a ele.
Inicialmente, a sintaxe poue iealmente paiecei um pouco estianha, mas no fim
uas contas ela bem simples:
objetoBestino mensagem
Bo lauo esqueiuo, voc sempie tem o objeto paia o qual voc quei enviai a
mensagem, uo lauo uiieito voc tem a mensagem que est senuo enviaua (o
mtouo que est senuo chamauo), tuuo isso uentio ue colchetes. No nosso caso,
onue fazemos "[[Conta alloc] init", estamos envianuo a mensagem ",==%+"
paia o objeto que iepiesenta a classe "Conta" e no valoi que ietoinauo poi esse
mtouo (um objeto Conta) fazemos a chamaua uo mtouo ""4"'". 0 iuioma
allocinit comum e peivasivo em toua a linguagem e exemplos ue couigo que
voc vai encontiai, mas evite fazei chamauas ue mtouo uentio ue chamauas ue
mtouo no seu couigo, a no sei que seja um caso muito simples como esse que
nos estamos venuo aqui.
Na segunua linha uo teste vemos o seguinte:
[conta depositar:200];
Nos enviamos a mensagem "uepositai" paia o objeto iepiesentauo pela vaiivel
"conta" com o paimetio 2uu. 0s ":" que nos usamos na uefinio uo mtouo
"uepositai" fazem iealmente paite uo nome uo mtouo, senuo obiigatoiio a sua
auio a chamaua (os mtouos que no auicionam ":" so os que no iecebem
paimetios).
No fim temos o couigo que faz a asseio uo teste:
STAssertTrue( [conta saldo] == 300, @"O saldo deve ser de
300 para que o teste falhe" );
Compaiamos ento o valoi uo saluo com Suu exatamente poique queiemos,
nesse piimeiio momento, vei o teste falhai. STAsseitTiue no um mtouo, mas
uma funo comum que voc uefiniiia como uma funo em C, ela faz paite uo
fiamewoik ue testes unitiios que vem poi pauio uentio uo Cocoa.
Agoia um uetalhe impoitante que poue passai uesapeicebiuo a uefinio uo
texto usauo como mensagem paia esse teste, em vez ue sei somente um conjunto
ue caiacteies entie aspas, h um "" antes uas aspas. Isso quei uizei que voc
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

16
no est usanuo uma stiing comum uo C, que um aiiay ue caiacteies, e sim um
objeto uo tipo NSStiing que auiciona viias funcionaliuaues as stiings comuns uo
C. A maioi paite uo couigo em 0bjective-C que liua com Stiings vai espeiai que
voc envie objetos uo tipo NSStiing, ento bom se acostumai a escievei
piimeiio a "" antes ue ueclaiai um stiing no seu couigo.
voltemos agoia paia o Xcoue, onue voc vai muuai o Taiget pauio paia Test,
veja como fazei isso na imagem abaixo:
Imagem 12 - A|terando o 1arget padro para 1est

Agoia estamos entianuo no mouo ue testes uo Xcoue vamos pouei comeai a
executai os testes, mas antes ue fazei isso piecisamos uizei paia o Taiget "F5?'"
onue ele vai achai a classe Conta, pois ela no foi auicionaua a ele. Pia fazei isso,
voc ueve selecionai o aiquivo "Conta.m" e aiiast-lo paia uentio ua pasta
"Compile Souices" uo Taiget "Test", como na imagem abaixo:
Imagem 13 - Drag e drop do arqu|vo "Conta.m" em 1est

Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

17
Com isso feito, pouemos finalmente executai o builu uo piojeto, pia fazei isso
uigite "Commanu + B". Apos alguns instantes o Xcoue ueve teiminai ue fazei o
builu e voc ueve vei um aviso no canto infeiioi uiieito ua feiiamenta inuicanuo
que existem uois eiios:
Imagem 14 - Ind|cao de erros de bu||d do kcode

Ao clicai nos eiios voc ueve vei a seguinte tela:
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

18
Imagem 1S - te|a de erros no bu||d do kcode

Como voc poue peicebei, o eiio na veiuaue no exatamente no builu, mas sim
no nosso teste unitiio que falhou, j que o valoi ua vaiivel no Suu e sim 2uu.
Paia vei essa tela sem tei que usai o mouse pia clicai no eiio basta fazei "Shift +
Commanu + B". Agoia que voc j viu a tela, tioque o Suu poi 2uu e execute o
builu mais uma vez com "Commanu + B", o seu builu ueve executai sem eiios,
agoia que o teste j est implementauo coiietamente.
vamos agoia uefinii os mtouos sacai e tiansfeiii na classe conta:
L|stagem 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 cheganuo l, o mtouo sacai tem a uefinio igual a uepositai,
mas o mtouo "tiansfeiii:paia:" (veja so como ele se chama) ueve estai uanuo
um no no seu ciebio nesse momento. vejamos:
- (BOOL) transferir: (float) valor para: (Conta *) destino;
Em 0bjective-C, quanuo voc tem um mtouo que iecebe viios paimetios,
voc piecisa "uiviuii" o nome uo mtouo em peuaos paia iecebei os
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

19
paimetios. Ento em vez ue simplesmente fazei um "tiansfeiii( uouble valoi,
Conta uestino )", como voc faiia em }ava ou C, voc quebia o nome uo mtouo
e tiansfoimai ele em "tiansfeiii: valoi paia: uestino".
Inicialmente a sintaxe paiece estianha, mas a piopiia leituia ua chamaua uo
mtouo fica mais simples e se voc tivei um mtouo que iecebe viios
paimetios ele com ceiteza vai ficai bem mais legivel, j que caua paimetio vai
tei o seu iuentificauoi antes.
vejamos agoia como fica a implementao uesses uois mtouos:
L|stagem 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 altuia uo campeonato, voc j sabe exatamente o que esse couigo touo
est fazenuo, ento vamos passai uiietamente pios testes, pia vei esses novos
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

2u
mtouos senuo exeicitauos. Em touos os nossos testes vamos, utilizai um objeto
conta, ento em vez ue ieciiai esse objeto a caua teste, vamos sei inteligentes
uefinii uma vaiivel ue instncia *%4', no nosso teste e implementai o mtouo
"set0p" que ciia a conta paia no iepetiimos essa opeiao:
L|stagem 8 - Conta1est.h
#import <SenTestingKit/SenTestingKit.h>

@class Conta;

@interface ContaTest : SenTestCase {
Conta * conta;
}

@end
Auicionamos a uefinio ua vaiivel ue instncia na classe, como espeiauo, mas o
que esse "class" que tambm est ai. 0 class em 0bjective-C uma
"foiwaiu iefeience" e noimalmente utilizauo em aiquivos ".h" paia que voc
uiga que o seu aiquivo uepenue ue uma classe em especifico, mas no vai fazei o
"impoit" uessa classe aqui, vai ueixai pia impoitai o aiquivo ua classe somente
no seu ".m". Se voc no colocai o class nem o "impoit" pia o aiquivo ua
classe no vai sei possivel compilai o couigo.
0m uetalhe impoitante uo "impoit" que quanuo o texto que vem apos ele est
entie ">" (como em #import <SenTestingKit/SenTestingKit.h>), isso
inuica ao compilauoi que ele ueve piocuiai esse aiquivo no "loau path" uo
sistema opeiacional, os lugaies onue ficam os aiquivos ".h" uo mesmo. Quanuo o
"impoit" apaiece usanuo aspas no conteuo a sei impoitauo, quei uizei que ele
ueve piocuiai uentio uos aiquivos locais uo piojeto (como em #import
"Conta.h").
vejamos agoia a implementao atual uos testes:
L|stagem 9 - Conta1est.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" );

Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

21
}

- (void) testDepositarComFalha {

[conta depositar:-150];
STAssertTrue( conta.saldo == 200, @"Valor do saldo no
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 no deve
ter se modificado" );

}

- (void) testSacarComValorNegativo {

[conta sacar: -100];
STAssertTrue( conta.saldo == 200, @"O saldo atual no 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" );
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

22

}

@end
Temos ento viios testes paia a implementao uas funcionaliuaues ua nossa
classe conta, eles so bem simples, mas tem uuas coisas impoitantes que no
uiscutimos ainua, a piimeiia essa:
conta.saldo == 200
Antes, no nosso teste, faziamos a chamaua assim:
[conta saldo] == 200
Em 0bjective-C, se voc tem um mtouo que no iecebe paimetios e ietoina
um valoi, esse mtouo poue sei chamauo como se ele fosse uma piopiieuaue uo
seu objeto, sem que voc tenha que fazei uma invocao explicita uo mesmo,
ento "conta.saluo" a mesma coisa que escievei "conta saluo", o compilauoi
vai fazei a mgica ue tiansfoimai o piimeiio no segunuo pia voc.
} o segunuo caso:
[ conta transferir:250 para: destino ]
Aqui nos vemos um exemplo ua chamaua uo mtouo "tiansfeiii:paia:", junto
com o tiansfeiii nos temos o valoi que vai sei tiansfeiiuo e logo uepois ue paia
temos o objeto que vai iecebei a tiansfeincia, veja que no existem viigulas
sepaianuo os paimetios, eles so sepaiauos noimalmente pelos espaos entie
os nomes que foimam o mtouo e os paimetios passauos.
Cr|ando um "construtor" para o nosso ob[eto conta
Como j comentamos antes, o pai "Conta alloc init" seive pia ciiai o objeto e
inicializ-lo uentio uo piojeto, mas e se nos quiseimos uefinii uma foima
peisonalizaua. Simples, ciiamos um mtouo ue inicializao. No nosso caso
queiemos pouei ciiai contas com um saluo que seja uifeiente ue zeio.
Comeamos poi uefinii o mtouo "initWithSaluo" em "Conta.h":
L|stagem 10 - Conta.h - dec|arando o mtodo |n|tW|thSa|do
#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
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

2S
Como no existem constiutoies iealmente uentio ua linguagem, o que nos
fazemos uefinii mtouos que inicializem o objeto com o valoi que nos
inteiessa, vejamos a implementao agoia pia entenuei um pouco mais o que
est acontecenuo e poique necessiio ciiai esses mtouos:
L|stagem 11 - Conta.m
#import "Conta.h"

@implementation Conta

- (Conta *) initWithSaldo:(float)valor {
if ( self = [ self init]) {
saldo = valor;
}
return self;
}
// todo aquele cdigo que voc j viu
@end
Nais um caso ue iuioma ua linguagem suige ento pia nos nesse momento:
if ( self = [ self init]) {
Poi mais estianho que paiea, esse couigo est iealmente atiibuinuo um valoi a
vaiivel "self" ("self" equivalente ao "this" em }ava e C, uma iefeincia paia
o objeto onue o mtouo em execuo atual foi chamauo) uentio uo seu objeto.
Nas poique algum iiia queiei fazei isso.
Na implementao ua Apple uo 0bjective-C existe um conceito chamauo ue
"class-clusteis". Quanuo voc ciia um objeto uo tipo NSStiing, o que voc iecebe
poue no sei exatamente um NSStiing, mas uma subclasse uele. As classes que
nos vemos "uo lauo ue foia" funcionam apenas como um meio pia se acessai as
classes que fazem iealmente o tiabalho, mas esses uetalhes ue implementao
ficam esconuiuos giaas a essa pequena mgica uo mtouo init (atiibuii um novo
valoi a self e ietoinai esse valoi).
No caso ua nossa classe no seiia necessiio fazei essa mgica, j que estamos
iealmente ietoinanuo uma conta, mas o iueal que voc constiua touos os seus
inicializauoies uessa foima paia que quanuo foi ciiai uma subclasse ue uma
classe pauio ua linguagem no se esquecei e teiminai com bugs estianhos no
seu couigo.
0utia coisa impoitante tambm lembiai-se ue chamai o mtouo ""4"'" ua sua
classe, se voc estivei implementanuo um novo inicializauoi (como nos fazemos
nesse couigo) ou chamai o mtouo "4"' ua sua supeiclasse (com supei init) se
voc estivei sobiescievenuo o mtouo ""4"'", assim voc no peiue o couigo ue
inicializao que j tenha siuo implementauo na classe atual e nas suas
supeiclasses.
Def|n|ndo propr|edades automat|camente nos ob[etos
Nos vimos que o compilauoi inteligente o suficiente pia aceitai que "conta
saluo" seja chamauo como "conta.saluo", mas alm uisso nos tambm pouemos
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

24
instiuii o compilauoi paia que ele geie os mtouos ue acesso paia as
piopiieuaues uos nossos objetos automaticamente (pense no "geneiate getteis
anu setteis" uo Eclipse ou attiaccessoi em Ruby). Pia isso, vamos uefinii novas
piopiieuaues na nossa classe, "agencia" e "conta". vejamos como fica o nosso
"Conta.h" agoia:
L|stagem 12 - Conta.h com as novas propr|edades def|n|das
#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
Nos uefinimos as uuas vaiiveis ue instncia, "agencia" e "conta", e logo uepois
temos as ueclaiaes uas piopiieuaues, com "piopeity":
@property (copy, nonatomic) NSString * conta;
Isso inuica ao compilauoi que nos vamos tei os mtouos abaixo uefiniuos:
- (NSStiing ) conta
- (voiu) setConta: ( NSStiing )
As instiues "copy" e "nonatomic" so atiibutos que vo sei utilizauos na
geiao ua implementao uos mtouos.
- "copy" inuica que quanuo um objeto foi iecebiuo como paimetio, ueve
sei ciiaua uma copia uesse objeto e essa copia quem vai sei atiibuiua a
vaiivel ue instncia, isso necessiio especialmente se voc est
iecebenuo uauos ua inteiface, pois os stiings que vem uela pouem sei
iecolhiuos ua memoiia a qualquei momento nos ambientes onue no h
coletoi ue lixo, como iPaus e iPhones.
- "nonatomic" inuica que os mtouos geiauos no vo fazei nenhum
contiole sobie o acesso ue foima concoiiente. Esse noimalmente o caso
pia maioi paite uas aplicaes, mas se voc vai utilizai esse objeto em um
ambiente com concoiincia, onue viias thieaus vo acessai o mesmo
objeto e chamai seus mtouos, ueve iemovei isso.
- "ieauonly" inuica que apenas o mtouo "gettei", que l o valoi ua vaiivel,
vai sei geiauo, o mtouo set, que alteia o valoi ua vaiivel no vai sei
geiauo.
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

2S
Com os mtouos uefiniuos, agoia voltamos pia "Conta.m" pia ueclaiai o couigo
que vai fazei com que os mtouos sejam iealmente geiauos, vejamos como fica o
couigo agoia:
L|stagem 13 - Conta.m com a def|n|o das propr|edades e gerenc|amento de
memr|a
#import "Conta.h"

@implementation Conta

@synthesize agencia, conta, saldo;

- (void) dealloc {
[ self.agencia release ];
[ self.conta release ];
[ super dealloc ];
}
// todo o resto do cdigo que voc j conhece aqui
@end
A mgica ue veiuaue vive no "synthesize", ele instiui o compilauoi a lei as
infoimaes uas piopiieuaues uefiniuas atiavs ue "piopeity" e geiai os
mtouos. }unto com isso chegamos a um uetalhe impoitante ua piogiamao
com 0bjective-C, especialmente se voc estivei planejanuo piogiamai paia i0S, o
geienciamento ue memoiia.
Com a uefinio uas piopiieuaues nos uefinimos tambm o mtouo "uealloc" que
chamauo quanuo um objeto vai sei iemoviuo ua memoiia, paia que ele possa
limpai ua memoiia tambm os objetos paia os quais ele aponta. Quanuo voc
est piogiamanuo em 0bjective-C paia i0S, no existe um coletoi ue lixo
automtico, libeiai a memoiia iesponsabiliuaue uo piogiamauoi, ento
necessiio que voc tome cuiuauo paia no vazai memoiia no seu couigo e
estouiai a memoiia uo uispositivo.
Em 0bjective-C o contiole ue memoiia, quanuo no feito atiavs uo coletoi ue
lixo, acontece atiavs ua contagem ue iefeiencias. Sempie que voc ciia um
objeto usanuo "alloc" ou "new" esse objeto fica com o contauoi ue iefeiencias em
1 (um), caua vez que voc chama "ietain" no objeto (como em "objeto ietain")
esse contauoi aumenta em um e caua vs que voc chama "ielease" (como em
"objeto ielease") o contauoi uiminui em 1. Quanuo o contauoi ue iefeiencias
atingii u, o objeto iemoviuo ua memoiia.
No nosso caso, as piopiieuaues "conta" e "agencia" so uefiniuas como "copy",
isso quei uizei que o objeto que vai sei colocauo na vaiivel ue instncia vai sei
clonauo e o clone o objeto que vai finalmente ficai uisponivel paia a nossa
classe. Como o clone um objeto iecm-ciiauo com base em outio objeto a sua
contagem ue iefeiencias 1 (um), o que quei uizei que quanuo chamaimos
"ielease" neles, eles vo sei iemoviuos ua memoiia.
Pia limpai a memoiia que estamos usanuo, piecisamos ajustai o nosso teste
paia fazei o "ielease" uos objetos conta que esto senuo ciiauos. vamos fazei o
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

26
ielease ua vaiivel ue instncia conta no mtouo teaiBown e ua conta uestino
em caua um uos testes, vejamos o que muua na nossa classe teste:
L|stagem 14 - Conta1est.m com o cd|go de gerenc|amento de memr|a
@implementation ContaTest

//mtodos no mostrados aqui no 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
Cuiso ue uesenvolvimento ue aplicaes paia i0S usanuo 0bjective-C
Nauiicio Linhaies

27
Auicionamos a nossa implementao o mtouo "teaiBown" que envia um
"ielease" paia o objeto conta e tambm fazemos o ielease uos objetos uestino
ciiauos nos testes ue tiansfeincia. voc nunca ueve chamai o mtouo uealloc
uiietamente nos seus objetos, sempie chame ielease e ueixe que o piopiio
iuntime uo 0bjective-C vai fazei a chamaua a uealloc quanuo foi a hoia coiieta.
E possivel uefinii algumas iegiinhas bsicas na hoia ue liuai com a geincia ue
memoiia em aplicaes esciitas em 0bjective-C:
Se voc pegou um objeto atiavs ue "allocnewcopy", esse objeto tem
um contauoi ue 1 e voc ueve se lembiai ue libeiai esse objeto quanuo
ele no foi mais necessiio
Se voc pegou um objeto ue outio lugai, assuma que ele tem um contauoi
ue 1, se voc so vai us-lo e ueixai ele pia l, no faa naua com ele, quem
passou ele pia voc piovavelmente vai limp-lo quanuo foi necessiio.
Se voc piecisa mantei um objeto iecebiuo ue outio lugai paia us-lo em
outio momento, chame "ietain" nele paia que o contauoi aumente paia
"2", assim quanuo quem lhe passou esse objeto chamai "ielease" nele o
contauoi vai baixai pia "1" e o objeto ainua no vai sei libeiauo ua
memoiia.
Sempie que voc u "ietain" em um objeto, ueve gaiantii que vai uai um
"ielease" nele em algum momento, se voc no uei o "ielease", com
ceiteza vai estai vazanuo memoiia na sua aplicao
ueienciamento ue memoiia um topico longo e vamos nos apiofunuai mais nele
confoime avanamos paia a constiuo uas nossas aplicaes paia i0S, essa
intiouuo apenas paia que voc entenua o bsico ue como esse conceito
funciona uentio ua linguagem.

Вам также может понравиться