You are on page 1of 76

BECOME AN XCODER 





BECOME AN XCODER  



Copyright 2006 by Bert Altenburg, Alex Clarke and Philippe Mougin. Version 1.2.
Attribution: The licensors, Bert Altenburg, Alex Clarke and Philippe Mougin, permit others to copy,
modify and distribute the work. In return, the licensees must give the original authors credit.
Non-commercial: The licensors permit others to copy, modify and distribute the work and use the
work in paid-for and free courses. In return, licensees may not sell the work itself, although it may
accompany other work that is sold.

BECOME AN XCODER T '

P

P
MS

__________________________________________________ 4

; 0 =

0C% *______________________________________

5

; 1 =

1A?,<(+ _____________________________

7

; 2 =

BD2 @&8$__________________________

13

; 3 =

#______________________________________________

14

; 4 =

OG_______________________________________

20

; 5 =

KRI7A_____________________________________

25

; 6 =

9-__________________________________________

33

; 7 =

! while ".L-_______________________________

36

; 8 =

1F!)
/GUI(A___________________

39

; 9 =

>Q &_______________________________________

55

; 10 = awakeFromNib_____________________________________ 59
; 11 = +J______________________________________________

61
; 12 = ______________________________________________

63
; 13 = 5______________________________________________

69
; 14 = 3NTH:_________________________________________

73
; 15 = 6E4__________________________________________

75

BECOME AN XCODER /!m

Apple [g?0]n Cocoa =gn_C$~Ln


b7 Xcode n_t9n Mac OS X fo)%1 Apple n

L
-?X Mac =n;I~,:?X=
.w,Z0 Objective-C V Xcode ]=nN
{)%z'S?OZ0o (GUI) n.=6:{
<Hz3_OZ0on=C9N.{vn
J;],8?:njGI~V
y 8.*~ sC

<HZ0.
<anXZ0<nq2
X+
PzRE^@@Xa @X
n6]X+n<A])%?nan5V$
aXp@n?Y"=.)%K>nc
y
.(Mn\`(Ma:Fn=unP9
\R\0"|i\<[4]n\(M^Ff
%n=nlPZ0@]q2\enF\<
[4.3] &q\ [4] n F9rn=#P9=g9Fn{h
B\<
volume = baseArea * height;

// [4.3]

=~nJ}U,X VT.
ng?kD
^.xfoU<H
=\+.~O=ng%S?4Hna Xcode8A
dPzR @ @nX\V$=
XQ]W~<HJn

BECOME AN XCODER 8$~

0 Fat

0
Fat
aWNg\UEa4l Mac bHc Macintosh
i:2 *.0)qZ+!73)mR%
|
1. Mi: MacyiX O MacDN) Mac (
 Mac ) Objective-C v AppleScript g5
:F9Fi: AppleScript 0)
aW#- AppleScript for Absolute Starters0)F)^r
http://www.macscripter.net/books

2.  Macintosh flA& ;gc i: PCFC


 Mac T %|TMbGF0) Mac f%|IzR
Sx Mac :K_mK Mac
:?

Kdistributed computing, DC)Y:hdM:
p kI Folding@home  SETI@home5:l0)
 WK1 DC "g'tLU =h DC "
)V>RIz8F Mac R ? KDC
"<o.SDN{p58FRZp Mac s
 DC F5B`LIz/
Mac
0)R.5BJ0)qZ Mac 
BDNn+73i:0)p Mac GHMG@( DC
"kI}  DC 
http://distributedcomputing.info/projects.html

 5, 
3. u Macintosh 73M2Q
L
Mjfwi:[i:
P'5
]5Dp0jUlE

4. i:2 Macintosh 60Rje


BECOME AN XCODER I &

6 0 : /?$ )

5. D9= 04B<7-FE' Macintosh "(>/83


!
#3%( .G+H>/
@5,;A0 DC * C'21J/?$

BECOME AN XCODER *v

1 ?Ew!

1
?Ew!
=r^';a' 6uz^?
T;aZ:M~w?=3:YAk^
}1^ c+ Xcode e?`0F< 
qwSTw?gw1SJ+b
{w(e Objective-C ?
'bT 
2+6=
 = 3 * 4 * : +ey.
D iC w x y ww5
8m#jn
wVg
2+6=x
y=3*4
Objective-C c+$+e| ylw5> d=
>  Objective-C %statement/LD?+el
lw
[1]
x = 4;

x l 4 sg :%Qw9AC_7X%
%HN...d [1] w?:#G
&P2xF 7BSIw?compilereT
w>@Ew Mac ow 0 1pC\

w>{Ow7B&bd=%HQwC
c+w-w
=r:?R ?t_ y&t@w Mac #D
w?I=rYtw?&4,C=3S
:)ew[gw&hKU"w9
5(]pC\`YAwGfAw5#?W
qWq::?wJ;

BECOME AN XCODER (i

1 =vDju

=j8 xbugR!X(&x
debugging
6?8(j=PJ\* x U>j4]9*^n-
rj4#x pictureWidth [2]
[2]
pictureWidth = 8;

O h#+?`=|vog}j_
{gjv=jv3j.K>U>\*v>j
4 pictureWidth pictureWIDTHcm PictureWidth y3]P
5 :^Hx4_:0_T::)
938] [2] dV[qP7~I |=6x@!
j#b
4v"M:cmB:)
> jA+^a4G>Zq{;@P#Q&0
2!GvWo';j{qvj4v
Objective-C jp:.K8 Objective-C >j:+5:^
Hx4]9 pictureWidthv<0jx {pt4j#bs
84\*:)9f;Zq=j#
9ft{1ZqNw :)\*: vj
Gv4\*:$ \*jv:"_"
 vZ4j]
(j4door8kdo8orc do_or
j4door 8"M l,8doorv:
sj4Door8v:)
8Pk{9FP#*&C|Pzz*^|
j=L v*^H/Yj= [3]
[3]
pictureWidth=8;
pictureHeight=6;
pictureSurfaceArea=pictureWidth*pictureHeight;


%jl,X8 Ee4:%{=
SP#\*l,

BECOME AN XCODER "^

1 v1j8_i

[4]
pictureWidth = 8;
pictureHeight = 6;
pictureSurfaceArea = pictureWidth * pictureHeight;

,nnP [5]SjRvr
[5]
pictureWidth = 8;
pictureHeight = 4.5;
pictureSurfaceArea = pictureWidth * pictureHeight;

6K/2R>integersNB,r [5.1] [5.2]


nTP j#QqP.Dups78_ikv|W_4zd
O# J$P.VQ Y{floatingpoint
P [5] _1M~=,ZpF@ p,1O#wv
) ub:yC>&?Ya{,Xo_l
"h@v"
[6]
int pictureWidth;
float pictureHeight, pictureSurfaceArea;
pictureWidth = 8;
pictureHeight = 4.5;
pictureSurfaceArea = pictureWidth * pictureHeight;

, [6.1] 7int b pictureWidth jvinteger


7Du#
Rv)4h@ RvE+r [6.2] b[ Rv
j float {C>&?A '_,vP 3_j
pictureWidth Rvj(_C><nT_j.\int{
floatmt\jv{Ljl pictureSurfaceArea h@l{ [6.2]
lp`vb_jYv3'_U1pO
#'_6flGv T_e} 9*l
(_yg>,!Pj int floatp(_(_b%1
pe}"_M#"_b%]
L.\DupO#c Ypc_/U ue}_9x

ujH5Du3Rvvint float 3m;_g>#


Q0E YE_/, -_I  u>j long long double<
9

BECOME AN XCODER 'V

1 m3`9W_

AH`#l!rClLm=bm3foE(u
`{W=<`1;F/&pW}s
7"{XW8!`gW<`1S{Xm
Wk`gW{!xkWn@)Q5!)W:
[7]
unsigned int chocolateBarsInStock;

$>
W*!rbg.7 unsigned int !)/unsigned int [?Y+2 RP
R

{!6\BmFDk_N# [8]
[8]
int x = 10;
float y= 3.5, z = 42;

!{cG W
/ZiWICl8mjTCl!H) ,W'3WM`
operatorsJ8v&Wf
+ )J8

- )J8T
/ )J8tT
* )J8jT
H)G Cl!80Wf1S{ddwW Objective-C 3
foW3{xGqO!r`.blz%2Q4W
3foyx x = x + 1; h,b1I [9] P [10] iWT
[9]
x++;
[10]
++x;

KmI YD x
/aG|U ++ :R-ZP^`]heWd
 ~ JWI [11]  [12]
[11]
x = 10;

10

BECOME AN XCODER F

o 1 u Yx(vOr.GM

y = 2 * (x++);
[12]
x = 10;
y = 2 * (++x);

&< [11] A*Msf-Ly yB 20 , x yB 11QG&U [12.2]


x &W 2 f-Jv" 1%+z6] x yB 11 , y yB 22< [12] Gx
(< [13] G\CQ#
[13]
x = 10;
x++;
y = 2 * x;

%+x(pTZ9 O5>YU$,P&4Y G4Pqx(


'Cjm qYl[8*I/O bav!&+
'CjhenQHqjOt{/O4XwS2}j N=
7@G"L3c=* /  + - S)%+ 2 * 3 + 4 yB 10|;
Njg?"T0"GD2 * (3 + 4) yB 14
dDSjG:_1`%P&
[14, 15]

B^]*:#RR
VG<

[14]
int x = 5, y = 12, ratio;
ratio =

y / x;

[15]
float x = 5, y = 12, ratio;
ratio =

y / x;

&< [14] GkEzCO 2*&< [15] GoYkEzCOjTG


2.4
% OYjaiG  % GzCOoYoperando
Y~-dDG'CoYOK % G-PO8*@G
[16]
int x = 13, y = 5, remainder;
remainder =

x % y;

11

BECOME AN XCODER 4 

) 1 + "-,

*

( remainder /. 3! x . 2*y + 3

 

21 % 7 . 0

30 % 2 . 0

50 % 9 . 5

22 % 7 . 1

31 % 2 . 1

60 % 29 . 2

23 % 7 . 2

32 % 2 . 0

24 % 7 . 3

33 % 2 . 1

27 % 7 . 6

34 % 2 . 0

$#0

2&' %31

12

BECOME AN XCODER *v

2 V= uj

2
V= uj
`+=w4P"Pw<Te"m[Tr [1]
[1]
float pictureWidth, pictureHeight, pictureSurfaceArea;
pictureWidth = 8.0;
pictureHeight = 4.5;
pictureSurfaceArea = pictureWidth * pictureHeight;

2qP-oXbZwD*w<c}<
w[$&MwowH&=W:w/
;t=V=]<S&wciKw
<hl+cHw0{8ZPwz]
w<! [3)c97R8 w2
w;t^w<I $=a"OwS5B
wU x8w
d
//

8 Xcode Cw;t}[9DQ&ph /* */ 
/* 
AdD */

Xcode H=KGPws;F<#?A
wuuoutcommentQ0w<ph /* */ "
w+0w<cfw0_H<"
+cbc;tcw0k"!
Dw<cQ5wk>fV=cw0M*H
wm"Yw}Ew%! cs&hlH\=
Kw6<8A".L*hw
80w< J+c|]Nnyu,<
cw\bc;t*8g[`+h8(w
8w<+s@-=8<1
=Kw&iK[<r
(wb[V=~ P'9w6&8w
s 
13

BECOME AN XCODER 0p

3 a@

3
a@
b2xRbqt@ (AG)b#P Gq@LA~
YM9 Objective-C qh\R-sVq@|=Kq
=n@#PI

tq)+uTZ0C*~
7q@%;q@!<B=nA-;<
:0q|9ulQi_:9
C !o^@+Ul0
qX|S)+q"^]=%A)%1^
.}[)qn|%vq6 }[@^
||;`a@functionq)AEq8>%\18
>^c'a@Z[@G\1a@gu/9CW@F
Aa@;`main() a@$T main() a@+r;
GeG@
R

 main() a@[1]

[1]
main()
{
 // main() a@q@kC
}

) [1.1] 3a@84N "main" ^|,{&{"main" |w


>D main() a@|W@-AqM|fEqa@%1
5K@^+d8{q?;|A+qqM|R;/z+
; ^q [1.2,1.5] GA{R-SRq@j;{5K
Jk{qmHa@qR[@^ZS+j
b+$qJ [2]
[2]
main()
{
 // ;CyO
 float pictureWidth, pictureHeight, pictureSurfaceArea;
 // Rse[[

14

BECOME AN XCODER m 7

M 3 P -

 pictureWidth = 8.0;
 pictureHeight = 4.5;
 // 2<E9?_3V

9

 pictureSurfaceArea = pictureWidth * pictureHeight;


}

5(BklaTc. main() mR[Ae.Fi9'j(B`]>f%)


U^9Tcn(B,bCTL&+U^
F>9 main()
- (BH:C circleArea() - [3]
[3]
main()
{
 float pictureWidth, pictureHeight, pictureSurfaceArea;
 pictureWidth = 8.0;
 pictureHeight = 4.5;
 pictureSurfaceArea = pictureWidth * pictureHeight;
}
circleArea()

// [3.9]

{
}

O;hQ#<(B@ [3.9] 3W091-g)$"*Kd6Y-9ND


<!4 main() - m 9S\`-<I89
(B9Z- circleArea() XJ main() -/n(B==>"G. [4]
[4]
main()
{
 float pictureWidth, pictureHeight, pictureSurfaceArea,


circleRadius, circleSurfaceArea;

 pictureWidth

// [4.4]

= 8.0;

 pictureHeight = 4.5;
 circleRadius

= 5.0; // [4.7]

 pictureSurfaceArea =

pictureWidth * pictureHeight;

15

BECOME AN XCODER $Z

v 3 { J2

 // ?j/6L?j[J2
 circleSurfaceArea = circleArea(circleRadius); // [4.11]
}

Xyk~2I[z)DB5*CG [3]
?j float [4.4]D\Oinitialize circleRadius&<!
ki [4.7]|
X[c [4.11] 8y}c circleArea() J2wL[.0sS
C+ circleRadius wT/a!ck circleArea() J2[argument
 circleRadius [irwJ2 circleArea()J2 circleArea() @!S8[
:>3_!#-returnW?jlA/G [3] [ circleArea() J2
Hby'E [5]
XQ * circleArea() J2
[5]
circleArea(float theRadius) // [5.1]
{
 float theArea;
 // Mu pi hm r "
 theArea = 3.1416 * theRadius * theRadius; //[5.5]
 return theArea;
}

/ [5.1] ?jP circleArea() J2fkoi:e t4K_yki


w1/N+e theRadius [?jF%v k }c theArea H1/ [5.5]
g[W,6?j#/ [5.3] F%/ main J2 [4.4] [YH^=!
sXK theRadius [^=c/ [5.1] 8[aR>3[v [5.6] 8-WL
ykJ2[~2d|_/v [4.11] 8 circleSurfaceArea wxPeyki
/G [5] [J2>3pk. ?jB`PykJ2-[n];
e9f?jH:ykq:7B5(9[.,6/y?jV!c
U float ]; [6.1]
[6]
float circleArea(float theRadius)
{
 float theArea;
 theArea = 3.1416 * theRadius * theRadius;
 return theArea;
}

16

BECOME AN XCODER  K

g 3 l C+

)"g [6.1] 1Lg^*NLi^C+x&BL~`8 theArea L\V


I float R65W^q+hZ_dvE2I main() C+ L circleSurfaceArea
[4.11] -rX"L~`9)/Bm<-e'i>z:]
=OH-LC+kY4)J<- T| oVvL8@]VM
L
[7]
int throwDice()
{


int noOfEyes;

// B,I 1 D 6 twLq+

return noOfEyes;

=OH-LC+ky&x^\)J^C+<-&x\I void R60


return [QV-nL)Jd@Q return * Sm
r 3
\G$
[8]
void beepXTimes(int x);
{


// p x .Lq+

return;

)J^C+-(I^mFL pictureSurfaceArea() C+#^t


Yj|s
[9]
float pictureSurfaceArea(float theWidth, float theHeight)
{


// q+'/

main() C+?{A}Y&x^%/<L-^ return [


}Y&x 0[10.10]BNi^C+u7c1<- 3bUo main() C+&x
^:]v' main() P "int" [10.1]:];f'H-Lq+!'a
[10]

17

BECOME AN XCODER $ [

z 3  O/

int main()
{
 float pictureWidth, pictureHeight, pictureSurfaceArea,


circleRadius, circleSurfaceArea;

 pictureWidth = 8;
 pictureHeight = 4.5;
 circleRadius = 5.0;
 pictureSurfaceArea =

pictureWidth * pictureHeight;

 circleSurfaceArea = circleArea(circleRadius);
 return 0;  // [10.10]
}
float circleArea(float theRadius)

// [10.13]

{
 float theArea;
 theArea = 3.1416 * theRadius * theRadius;
 return theArea;
}

.w-L [10] VFBm-z [10.1] 50n main() O/-z [10.13] 50n4


T\O/.YBm}'/t
M-z [10.9] 5
`" ]0&7+g circleArea() \O/ghrM8v main() O/
SQciPfn" \X6" )
3wn<
warningjGj-= int main() \k _ O/`< function
declaration; [11.1]}D0>"z [10.13] 5s@
!
[11]
float circleArea(float theRadius);

// O/`<

int main()
{

Z/\N~'H#*uL [10]
BmbAjM\}n/9ej(CJ
M\Ix{y?
Bm/oawC^d/#M\)%UEq-Bm\/p0n
rectangleArea() O/
lL [12] \3}nO/-Bm\ main() O/
R;KBmW-nO/ \/|%1}e0:\,g.2M

18

BECOME AN XCODER .n

3 b@

main() b@j>l-o@U$&Ii
@JoLj\:~&+Ii|b@:C/d
o}sHo*D)}b@o*O&UoLj
=,'z
[12]
float rectangleArea(float length, float width)
{
 return (length * width);
}

>hX<o^&A** [12.3] 7Z;


lTu< [10.15] ]/Zt-o theArea ){~81>J<b
@xP
T<Efob@ypK{+i3[{tANoY
{&!Vb@vc(+o@)WAVb@oxP2O+
oFo
^_&!Vb@o9K{+v.LDQ5
@oa"4a"
&!b@D&!<Q5+Lom ]
/+hqo)A>J]/b@ {
 b@o9?
 b@oR!wM
 b@;So!lowM
<^ [12] \M{
 rectangleArea
 `{ float#rs #r
 b@;|kGDl{ float wM&!0* [12.1] o
?q
<b@o@ @_ a"b@{ Objective-C 
&go%<T6BF~K{<Te Xcode
ZF o@ [11]

19

BECOME AN XCODER #V

y 4  +,/

y4
+,/
?h /?hW4 5E1Wk;a?hGC5vnd`A?hWeS
'K5||00WUAS'/ /~"m?hsH$i Cocoa
OIWL4NSLog() L4~aiR.bx/us $*bdAuWS
"+," M 7NY):4
NSLog() L4da}eK'ol7 a$K4SW;a.b
jQH$O?h/"mW$UK'?hWS!u Cocoa B
t_usH$Bb W@ 
?hKcc NSLog() L4d`H$
[1]
int main()
{
 NSLog(@"Julia is a pretty actress.");
 return 0;
}

r8_J [1] Wf3 "Julia is a pretty actress." 'KP @" " W


3{b39string
q39"FNSLog() L4+,|0WoJ2&\W4-
JK/?WDz 4 [1] W>2
2005-12-22 17:39:23.084 test[399] Julia is a pretty actress.

i39=N0i3character
T/wKWJ5 main() L4Wgdf {+
[2]
NSLog(@"");
NSLog(@" ");

f [2.1] =i3
{bX39empty string(<WZ]bf
[2.2] G[X39cpK^=iX%space.6~i39WZ]
a 1

20

BECOME AN XCODER '[

} 4 -.0

04;Go>\4B-J6om\HIgvMCk#\_
l4-.L\9lom\%ALh# [3.1] lb \n]
94
[3]
NSLog(@"Julia is a pretty \nactress.");

{0XfrI3 "6e\-
Julia is a pretty
actress.

0 [3.1] \zd~escape4$@ NSLog() K5 l4bq(


I-.L \48b6om\40&H "n" ] "Q9"
0cGyZ xg.lzL 2bls3Xl<0z
_i\46omE`p.lzOCk"g0z\^i
F b_iV!lz?@ NSLog() K5l}
lz
+? 1I\lbg.I\8$\,=omgT|S
blH
[4]
NSLog(@"Julia is a pretty actress.\\n");

h# [4.1] t9_\Xb
Julia is a pretty actress.\n

L)^dCk"6*PR\4;{0CkD_\X.L 
[5]
int x, integerToDisplay;
x = 1;
integerToDisplay = 5 + x;
NSLog(@"The value of the integer is %d.", integerToDisplay);

Y0aCk6l4;ll/l4;A G6
\W:%dz74 % 6o>\$_il d decimal number \t9_0 %d U0\<u _\W:+
? integerToDisplay \jt9H [5] wL
The value of the integer is 6.

g*nx%( %f N %d
[6]

21

BECOME AN XCODER  B

d 4 i !"%{

float x, floatToDisplay;
x = 12345.09876;
floatToDisplay = x/3.1416;
NSLog(@"The value of the float is %f.", floatToDisplay);

Q&.C)Y( MCh ;4@`'ArQ9.C)Y(


`vQ3 .2 ?: % ~ f qjzUg
[7]
float x, floatToDisplay;
x = 12345.09876;
floatToDisplay = x/3.1416;
NSLog(@"The value of the float is %.2f.", floatToDisplay);

mMu`Dx'/TR} M`
fsrQLXVG\rzXo~
tKkG'A`Q|HCg5V`s1b%9 CVwZ)p<=C
K`% % ~ f q>F % ~ d q8N=gXKl+'A`N=
CKVCK [_saVCK
[8]
int x = 123456;
NSLog(@"%2d", x);
NSLog(@"%4d", x);
NSLog(@"%6d", x);
NSLog(@"%8d", x);

7 [8] )p'C
123456
123456
123456
123456

%9XS [8.1, 8.2] 2WJ0nQCV6CEq @OEqje,


^)S [8.4] N=CKgXV$*2WP:CEcGy
COI]ngXVCEq
#[N=QCK~ C.
O-C
[9]
float x = 1234.5678
NSLog(@"Reserve a space of 10, and show 2 significant digits.");
NSLog(@"%10.2d", x);

22

BECOME AN XCODER B

_ 4 b "#%u

peK &= Q:!,]$&vG.CyOJC [10.3]-J\k{E)


pC5 %d w %f 7z>sSG.intfloat
[10]
int x = 8;
float pi = 3.1416;
NSLog(@"The integer value is %d, whereas the float value is %f.", x, pi);

tyG.5{C`qJHMKC'@\4_ Q2
_ QTdA
{C 6'
[10b]
int x = 8;
float pi = 3.1416;
NSLog(@"The integer value is %f, whereas the float value is %f.", x, pi);

h
"C
The integer value is 0.000000, whereas the float value is 0.000000.

^%jY*3PC_ Qf(c QXw Qrg3PCf(x NSLog() aQ


8(mnVD3P0i/FC{JxKW93PCf(k0i}
l import1 NSLog() 8(Cp8(R~5 NCL
#import <Foundation/Foundation.h>

aQLkJ3Pf(C_ Lp3P4%b9C;)?+<% UI


3P[9
NCf(|3PZo% bY*
[11]
#import <Foundation/Foundation.h>
float circleArea(float theRadius);
float rectangleArea(float width, float height);
int main()
{
 float pictureWidth, pictureHeight, pictureSurfaceArea,


circleRadius, circleSurfaceArea;

 pictureWidth

= 8.0;

 pictureHeight = 4.5;
 circleRadius

= 5.0;

 pictureSurfaceArea = rectangleArea(pictureWidth, pictureHeight);


 circleSurfaceArea

= circleArea(circleRadius);

23

BECOME AN XCODER 

 4   

NSLog(@"Area of circle: %10.2f.", circleSurfaceArea);


NSLog(@"Area of picture: %f. ", pictureSurfaceArea);
return 0;
}
float circleArea(float theRadius)

// 

{
float theArea;
theArea = 3.1416 * theRadius * theRadius;
return theArea;
}
float rectangleArea(float width, float height) // 

{
return width * height;
}

24

BECOME AN XCODER J

s 5 v i.)

s5v
i.)
8[DQUHCK) TM/WlK'|->@
%1TnK Mac ->y<nK Mac Tt_\dcK
)UcompilerT$9nK)z* Mac Hfi.Ki.aH
KT Apple K2 Xcode )uYKn B Mac OS X HN

K!(% Xcode1T{&0Fn+wKJnm
http://developer.apple.com K}L# DX2*U^
r$pg Xcoden$ Developer `6 K Applications `6 :Dns
,pgKa]hnAh"?AuK=+P-&InX
K~Sa$ Preferences ;[XeKEm File x New Project\5jb3qxKyr

Xcode 4)nR

jb

8[XB Objective-C R \Okx=+ GUI7BLVZGraphical User


InterfaceK)HG o$ Command Line Utility K Foundation Tool
25

BECOME AN XCODER

P

v 5 } k1-

zMlhQ'2

ZpQ"- c'+G*
W
Finish

justatryDLcp_"H,plhQ2

;bs(_V&Qlh#xTerminalk1*Op8rpQ-#x
k1D_4E~CMplhQ'/c^+0
/cGX#xNk1Q-'+vc+! _ \Q/9
[aQ-'T" +!
s(cBZ-z`eQpmnn]KQ5s(puS{c/Ici
YQiYX "Groups & Files""H,Lw.p-QN/h$S{@/)
h3XWpV&)AQ GUI -g({m<KpQ GUI t)AN
_Qh{EhywDR,(h73X*Op({Eh7U
NXcode F{EQh7"Groups"HwpQ>f
({c'Z Groups & Files QiYqw justatry KaQ Source wa/
c'Z justatry.m [1] Qhjo?c-|6c'Z main() QJ-{
X6/ main() J-QCch(}W;bmd=6;b-Q-
*OpQ% justatry.mpmsc:QApple ZpV&
 main() J-

26

BECOME AN XCODER 7

+ 5 - 451(.

Xcode 6 main() 

[1]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) // [1.3]
{
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // [1.5]
 // insert code here...
 NSLog(@"Hello, World!");
 [pool release]; //[1.9]
 return 0;
}

"",&.*2)

* "

  NSLog() /3#

import $  0'

 main() 
 
%.7

!0
27

BECOME AN XCODER ,{

5 GB

 .i1[\[|Bv=b
  NSlog (.i= 8AI
 return 0; (
Ce|xH
 jiC|U= main() lB| [1.3]
 / NSAutoreleasePool o|( [1.5]
 ')&S pool release jA|( [1.9]
[i[O~@O~[|B$[|(

:[|[CZ`[5
X "lB" r@EDm>r}l
B.iB|z^B main() lB!lB
F[+t=`CzV6=h [1] m|sCxH[|
u+_5qe( [1.31.5 1.9]Cek"w ObjectiveC a|xH+5|B?j
T| i| |[7meT|xH
@y|`Cm4L3|p |Jw main lB|
GBs||BM.|Bf.V
k*|B.*OBs||O
9|f.V+*bjC "pool" A|
(=|d
[G Apple sg|B [1] 1 Build and Go | 1i2
buildR compilecGB

Build and Go 

BGFyKe)|8= Run Log G


BexitedR stoppedc < 0m| main() lB
s<|@9[= [7.9] sm|;E[|BQGm
Gc`C]m0Q
[<mh [1] c@yBC-dhi[.P|(n
# NSLog (N[ "Y" % .i1(W|

28

BECOME AN XCODER Q

w 5 z n4.

[2]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 // insert code here...
 NSLog(@"Julia is a pretty actress")
 [pool release];

//{{;

//[2.9]

 return 0;
}

^V!xd.X
H%S Build

d]3Sm+_ [2.9] Uv

Xcode Yd

,Or
R% v4xdSN
error: parse error before "release".

PparseZb#^7SBs@>4.A[Z9>
4\J8'd&y"Sr~Di(1M import _
[2.1]r~Dd-#\_S: [2.8]r~D
Iw [2.9] 4gvBs2AlAZ+x42Z
+SUax4+xpIS`^ukZ^~D/S)|
6ZxC)|?phSl/WS}_L)|S5 ?pZ.h
S*jWtT
FexdlA$0n4.Ko7
v+<c=q zfFS.G Apple ~DS. [1] pIE [3]
[3]
#import <Foundation/Foundation.h>
float circleArea(float theRadius);

// [3.3]

29

BECOME AN XCODER B




- 5 / =A:*1

int main (int argc, const char * argv[])

// [3.5]

{
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 int pictureWidth;
 float pictureHeight, pictureSurfaceArea,


circleRadius, circleSurfaceArea;

 pictureWidth = 8;
 pictureHeight = 4.5;
 circleRadius = 5.0;
 pictureSurfaceArea =

pictureWidth * pictureHeight;

 circleSurfaceArea = circleArea(circleRadius);
 NSLog(@"Area of picture: %f.


Area of circle: %10.2f.",

pictureSurfaceArea, circleSurfaceArea);

 [pool release];
 return 0;
}
float circleArea(float theRadius)

// [3.22]

{
 float theArea;
 theArea = 3.1416 * theRadius * theRadius;
 return theArea;
}
float rectangleArea(float width, float height)

// [3.29]

{
 return width * height;
}

!@)4;,7.(1 29' main() # '  circleArea() [3.22] rectangleArea() [3.29] "?0'8  ' 
main()  [3.5] %6 ' main() B 1< Apple 3' 

51*$'+&

> 

Area of picture: 36.000000.

Area of circle:

78.54.

justatry has exited with status 0.

30

BECOME AN XCODER ~ 2

L 5 R m{fF&X

bX }Inx
}IzEw"!CAJ`_<X F&C)QW
h*$ Xcode O*}IB0<J_<4d}j?3=6>#%yDMt
Xcode T`U@ " ut"breakpoint@v#%3lse5

J3X

k N-@ ut

o1]JG`:-3=F&6;,}j3?"PHJ`g<( ut/J^.
p3=37>&
Ko9|38Z ' 3L@as8\ /V7T`!@rSc+

Build and Go i

rSpopup menu

rq Build and DebugJ`;, 3[Y

31

BECOME AN XCODER  >

\ 5 _ xpS%e!

Xcode debugger X..@S%e!1mJv

^Pe!TiS%A6:k\P {z <XHJ /@M=XTJ6P


v@N'#V P {zE]78,@NiK$4LS%y3
Continue Ff^P debugger GPU
@ 5ydh?4wW
*O["9"rL@;&utQ}pS%|`@ Mac OS X e!
<X nq(l)3CIM@e!X[RrL(@2YaGsX@
Objective-C B~Xgc-o@Dl)IMe!Z4@bP_j *OaG
L(^20E*Oi+ GUI e!y

32

BECOME AN XCODER }?

Z6`X

I

Z6`
X
*MLVHV@d(v%[#EKX
)^Ku@ [1.2]

I
M U,S/*E5N0@{z'aD9n

[1]
int age = 42;
if (age > 30)

// [j > A " <"

{
 NSLog(@"age is older than thirty.");

//[1.4]

}
NSLog(@"Finished."); //[1.6]

Z [1.2] ,Y if... B]pFX BVG:o Cj Cj@D


*i Cj@|yq(f=F trueOM HU,@;*d(v%^k&=X
age > 30 )3s% [1.4] ,@'-ah]"9.Dcx^KX )r1%Z
[1.6] ,@'-_h]"9$F% if Tg@ Cj
2JPhb7\BDiX

)M;HU,@^H6 if...else I [2]

[2]
int age = 42;
if (age > 30)
{
 NSLog(@"age is older than thirty.");

//[2.4]

}
else
{
 NSLog(@"age is not older thirty.");

//[2.7]

}
NSLog(@"Finished."); //[1.6]

%I [2.7] @'-*%X

)M h]"9+^4 Dw8 [2] @W>

RI [2.2] @ <[jQot'@lmq


_!Vm
==

e<

>

<
33

BECOME AN XCODER #T

<

Q

>=

QOQ

<=

QOQ

!=

Q

6 (h

v<wQ - `In ZrR-c@{7 nLV


`p0`^K -6n^Kcanl`fXW
zV2VDq-. VMHA.`>dVto@{
%In
 .gi:h5t[4%`
V;k)Amg)|
F"Hy%JV if hN
AmVee9(En .InyN$nS
` truex` false~
. Objective-C true false <Y&c 1 04,c BOOL Vvus?
% HY&FlgY& "true"3 1 O YESgY& "false"
3 0 O NO
[3]
int x = 3;
BOOL y;
y = (x == 4);

// y ` 0

1Sg+tb/n(C`9V1S4/QnV(!*3'
G% AND `In & HY&&&1Sg8n(3'=
G% OR `In | HY&||
[4]
if ( (age >= 18) && (age < 65) )
{
 NSLog(@"Probably has to work for a living.");
}

gUVB(h}H `9VgVBn(hPJn(h
V _=k)jV()1S3'jV
nh
\]

[5]
if (age >= 18)
{

34

BECOME AN XCODER  

6


 if (age < 65)


 {
  NSLog(@"Probably has to work for a living.");
 }
}

35

BECOME AN XCODER %W

y 7 ~ H& while Ked!

y7~
H& while Ked!
M'[bBhumXQ64F!d!}
4Ker:L4X4 [1]

r:7Bh17NL

[1]
NSLog(@"Julia is a pretty actress.");
NSLog(@"Julia is a pretty actress.");
NSLog(@"Julia is a pretty actress.");

>@Z28"ceXN6ljtcr:P1!d!79Q6
X4GObjective-C IiVKM"
2UtY|id!P|zd!cer:X7tJ [2] 0
for d!A|i3K^OeX7|i3#a/btVsip?
eJK 2.7 7
[2]
int x;
for (x = 1; x <= 10; x++)
{
 NSLog(@"Julia is a pretty actress.");
}
NSLog(@"The value of x is %d", x);

0J [2] 3; [1.4] {-K 10 7f+x {^Ob 1]&BhR0


<X4x <= 10K=w*8l|iw*a5(X/b x S 1Q0
_Xd!{r:vx Xg0|a/b x++ |i4 X`
vx Xgx0a 2 ,kK 10 /b" S9S 10/8
0 _Xd!,7r:$ x 5 11w* x <= 10 ,
5(]X
!d! [2.6] a&K.tTnqloopD] x a 119a 10
otc XE)9a& x++ Ktc?X
9v KXJ [3] C\5\

6tcX4

[3]
float celsius, tempInFahrenheit;
for (tempInFahrenheit = 0; tempInFahrenheit <= 200; tempInFahrenheit =
tempInFahrenheit + 20)

36

BECOME AN XCODER Y -

C 7 G ( while *8T7

{
 celsius = (tempInFahrenheit - 32.0) * 5.0 / 9.0;
 NSLog(@"%10.2f -> %10.2f", tempInFahrenheit, celsius);
}

F;I.V


0.00 -> 

-17.78

20.00 -> 

-6.67

40.00 -> 

4.44

60.00 -> 

15.56

80.00 -> 

26.67

 100.00 -> 

37.78

 120.00 -> 

48.89

 140.00 -> 

60.00

 160.00 -> 

71.11

 180.00 -> 

82.22

 200.00 -> 

93.33

Objective-C

+P*8TD7

while () { }


do {} while ()

CP?Q': /<UO. for-loop &S;B%X$5=W,%


X.J,4 false loop .7H
LE@#
[4]
int counter = 1;
while (counter <= 10)
{
 NSLog(@"Julia is a pretty actress.\n");
 counter = counter + 1;
}
NSLog(@"The value of counter is %d", counter);

F;) MA 1.I R6 counter .9L4 11


>( do {} while () 23N K.70"L@#!
[5]

37

BECOME AN XCODER ?


1 7 3  while (;'

int counter = 1;
do
{
 NSLog(@"Julia is a pretty actress.\n");
 counter = counter + 1;
}
while (counter <= 10);
NSLog(@"The value of counter is %d", counter);

4" counter *6# 11


/7<.52&0@+: , 8> =3 +
%!+9 $)GUI1-5

38

BECOME AN XCODER #Y

8 q4?n (GUI) [2

8
q4?G%^nGUI[2
Objective-C \[@p=/Izeb'q4?G%^in
GUI[2<g@".5NT*EObjective-C E g,h C [2C
[6K&`h@pz[g[ CS Objective-C C KP4;r
r. "Objective" q+Objective-C uKqhZ*object[UQ
K&`h@pl.1`nK[Objective-C $1[
Q)> .yb'1D% J p[2l
1tH0m2_/%<g0X[2gqHIoV
2l3Va^MR^~0[2gq](A
lxv eM~0 Objective-C FW:w.
1gcgZ*[|G% Objective-C7O
l[Z*[d2I p
IjqH @pjjq Safari  Objective-C [2g0;
L[jj Mac S[q Safari ! B4
qfk8[gf
Sf qk8fIqt$EMq{smessage
}ql-q{s9F2I 7

39

BECOME AN XCODER

F

f 8 m W-7U (GUI) Hq,

W close ^Yh{_ujWvr

vrPWG$agDej WOyPG$aO Vj<G$(


-vH5d,2P:LC-HG$R*.=>!>K" Safari \
zktHG$( n9-WvH5d,

WG$=*jWvr6?HG$=*j<Oy

aCb|S-oW Safari vrn-oWa` Apple Hq,iTXP


a. JwxH
c|a]~|SoWpN;&iT)8WvrBI
b. 3Etemplate Safari Z!>M#j<vrG$
ps[P bVM# <q,Q4class!>@Pvr
H0QbehaveaM#W}vrZ; PjW4QaM# jWv
rjW4K WvrHA/%1vr lPjWAHW
instancen*' 76 P+jWAH

40

BECOME AN XCODER (n

8 @Q (GUI) p=

y+p8 Mac p~:lSminimizec


Dock {%%6c P/1p7}:HcpZ
}5Kg4p_8 pGDKp }
o,w@\p5BWo,@\D1p
o,h@pDY2E1
K[$}y+o,o,<daccess%"FpX0J
\Ja} close|
p "" ||
close Bo,o,"FpJmmethods
cp%eb=tzh:lRc])%
_9O
8Ky+o,{%uRAM_<pG
\apD%p=J-'Zp
}5-=W}p)_p=$
AI}Wo,<dkKp=
:1vcp8'cp= N\uj%6Xp
Dvs*pqcU{pRi
R_=%@`|button;Gtext field:l
|
| c;G:l|
#|;Gw
j #S%>@`|xp&pU
9"T:Hy+(pRVV_

Ry+p=p

:lR=pa||
%a NhFpmp3
%Lf8pZ^ close o
,%}Kp5BR8p}o,D%`|
?[M;Go,!*
5BR.y+REpK{y+%po,}\|
p?rC
po,Rp}o,I}

41

BECOME AN XCODER " Y

8 n7Ck (GUI) [5

Z* -[e~;n5[roDm0 h NDm[40U
[y 

Mac

Dm[6N&MncS{L[zpa[X~;nX
[5e=U@ :]!G ~;nX{nzp3=
Z*|3=Z*[.3zp\'5message sending expression

K[AUn3=@ fnX[.3 6Nnzpa


3=Z*~;nXDmin3=uc[cL'l/
9zp\'5 AZ*.X.7nn3=XS%N[
l

0Dm5 [Z*Q9zp)[x

Pe0 Objective-C 2>zp[wv5[1.1] F7: [1.2] 7


[1]
[receiver message];
[receiver message:argument];

0Ej hN[,[V<T0d :$_ 8[


%L?a0d 6Z*+ak[eX[.32W
nO[XiR1nl^
iJm [1.2]
DmhhI eb?[} Xcode H`(ns Application 
[ Cocoa Applicationa[sn.3cK[ GUI 5.3
3#0[ Xcode [ Groups & Files tg  Resources qB0
MainMenu.nib Double-click

42

BECOME AN XCODER w:

Q 8 V F'd-E (GUI) <Z&

# Xcode spqH MainMenu.nib

(GFZ&Interface BuilderKcNJm\S$][<OMIcaDL File


lWl5 Hide OthersMKcC4F][!B "Window" <][AMZ&</=K
cC4<]['r 6MIcaDjk< # "Window" ][<t'
F!gA "Cocoa-" _n<][AF#M< GUI 6'0/<;<`X"

RgB "E9]["palettes windowi@TF][< 2 <QFd.


7P1F@^4 GUI ][ "Window" @E9][ , <QF@^Y?u+<
7PF'\ "System Font Text" %<%v)4 GUI ][ 

LE9][7P GUI ;4MoZ&<][

#f?LE9][7PF@^4MoZ&][<TFJ,c>Fb<@^;
.K84M<][TFJ,e%v)3*MIcDLE9][74M]
[<;
Uh
43

BECOME AN XCODER (e

8 {8Fx (GUI) g6

b4`H2xag+ 8{05+TS4 NSButton Z


NSTextViewPq* Apple [RgB02'nGz!tV4>IVP
BgcPqGzu26<&g@[ug
H]V "Window" gf-3O$zVg 9{g
pf-T|J$ xg5GE2GzL{n
{xa
4>HUgf-Vg
uJ{f-gYpropertiesW$np
command-shiftiGz Ttt$STW "Window"!2%
Mgg Instances ytV$WTOp
command-shift-i4`2ig6
pop-up menu gq Attributes!H Textured Window Tg
7j#brushed-steel lookh+!dg;w6g#l)
.><6

Gz2 Interface Builder g~q$ginspector

kgGz2uTm,{B?q2XkGzK ttB
qo@g
rs
g6v@4`!Q)Bm,3g_=:);X
[8g_=Tm,;g6NST4`um,{8Y
 g"u ^PYg6C!:ur[8Ug<r
behavior4ZT6m,2Bg6v}D7g
_= Ag\inherit$[8g<r:q Objective-C C 8[/
g1

44

BECOME AN XCODER ,o

8 CO (GUI) qA

?IaqCKNSWindow<ZF' j
G*qK<$ ]HaqKFqBa
"close" -\e[TC*2IAF TC~WZ]A
aqK?lqKTC%NgmqA
GKijqK*q "K"superclassF?
qJ}H
&raRamhsajU
hierarchy of inheritanceq
?lmTCRa#qmSYq
L^YE Tm<n
Objective-C #signalerror
?ljGKqmJimplementGqH{x
' overridegqm_`' A|
|
<v4Q*a')qK.`qm
d Apple gqZ^.8q9:DqBa
HqmqFt Apple qZi <4#)zq

q/ Apple >PGq close mP
' invoke/PqKiJq close m*8qc
(A uPGq close mrecursiveqc(
[2]
// .`Qa')qAk<D
[super close]; // ^.Kq close m

3+ "FVFP yH
*
iCKq9 "NSObject" qK5w0h^.qKrh
q NSObject q Ksubclass_`NSWindow K NSResponder K
q KF*+X NSObject q KNSObject KgiCqp1i6.q
m_?-p1q@p1M' q
<P.=!avP`?Iw0K
a MainMenu.nib [b Classes <a NSObject K
b*za7q Classes b Subclass NSObject;a MainMenu.nib [q
K>9@PPqf9 "MAFoo"

45

BECOME AN XCODER !O

m 8 s _4>\ (GUI) Qy2

U& MAFoo <

MAFoo ~QE_ 1"R My Applicationhht/xN<+9W


 h~Jh6Q$y2?^Uh p: vWHEK_1
"$D:XhL4<QS;l4Q<+x#Zw5[$
NS,XVdhjkNS W{ Apple Q<B$QR NextStep
Apple } Next, Inc. VNextStep p_:Anv3X Mac OS X Qg5 Steve
Jobs Q-TWa
. CocoaDev Q wiki
=(;QFSQiuh.h6Q
Sb)Y http://www.cocoadev.com/index.pl?ChooseYourOwnPrefix
U&_<bh{Q+1[dMp_P'Q4$eCD
?^YG. Cocoa $DR|zQ<oI+X NSWindow_C W
$DR%7Q<oI+X NSColor.?^QC ?^``U&Q MAFoo
<.pW$DNP'.y2W08r.fQpvWX?^{QW
_@4c<Qq$+1
-G Interface BuilderH Classes uQ Instantiate MAFoo v0*h. Instances ]YGQl.h4_+X MAFoo Q%p_%R?^``
U&Q

U&_ MAFoo Q

46

BECOME AN XCODER ! W

} 8 i2=e (GUI) Y1

>hY A`c]%#GtrmY_N>hY MAFoo X&Y4


>h c]%i# MAFoo X&N07Y,brmy~ti0
7X&/TiX&C2iMX&YwreferenceyVtrmi
X&-_>hY MAFoo ]%>hI4_i>h MAFoo
X&YwH"iwi_trm>hY MAFoo X&*Y]
%i#>hYX&Ni07Yy\Ztrm^Z
>h)3i1c9YF|_~_ YnjBi_opQ
Yv9tirmM ;Rcx6Y MAFoo :VY+irmt>
hkk]%Y MAFoo :YMAFoo X&MAFoo X& DEC2;6iv
9Y18` MAFoo :2,4it MAFoo X&Yrmtriggeri FAFoo :YVK9a&F- J tirm07X&
Birm;iVY+0-iJ i07X&YVY'u
`$igig~9birmY(507
csVY+s
~t
>hY:cLiv9Vh~LiX&P4ci
outlet`i"KqliX& `i07X&`Rctr
mY
Q- MainFile.nib Y Classes f MAFoo `~OsKY^-{Y
_
command-shift-i K?i:Y inspector zN
- inspector 
O Action fE Add _Kiv9action `VN MAFoo :
"i@2Y+0JK{ "setTo5:",b>hcdiV-
07
$0 5KO# Interface Builder RIY+iVE
i+0J/ "reset:",b>hcd-07 $0 0U>
hYV+0[":"<^>hN@.SiYF

47

BECOME AN XCODER e 0

A 8 D >S" ; (GUI) 2G

OW?

/+ MAFoo a!

@ inspector KH ^, Outlet <OW> outlet (J>) "textField"

OW> outlet + MAFoo a!

4*>1M2CI 3#=:J#=2*>6LNQ27FA>6L
8::'#=2 MAFoo Teb dX 5#=E$-9 "Set to 5"#=

P[R:%c6L2\V `_F5]O2Y2#=$
A>6L-9 "Reset"Z.NJ#=26L>>!2B>&fU#=2G

48

BECOME AN XCODER  =

W 8 [ N'q/K (GUI) ?_%

%O+zn*(23 FJ?YF!G0M-T0M?4@HKsXv4@(
2Fuc'gm?
V"0M lj\#JrxB?Za
a) "Dd "Reset" w MAFoo rf
b) "Dd "Set to 5" w MAFoo rf
c) " MAFoo rw$)f
JBZa" MainFile.nib b`  Instances L^CDSy ? Control 3
ipR Reset Dd96 MaFoo r  JRI? 9o5}t QhV
UAYNZa?{z8YU{FDdE6 MAFoo r^C:eip

1NDdZa6 MAFoo >

kS:eipCDd? inspector hNZaK; K MAFoo > 


?P*<~7|k?P*
]F "reset:"^C Connect Dd5,&Za_.

49

BECOME AN XCODER 
7

Z 8 a D{& A (GUI) 9f

 inspector
;_i

W^D=m:ID}'C MAFoo 89Ost\=Gr( reset: JEp


Lj
TW9f%( Set to 5 =m_i. MAFoo 8
@ MAFoo 8!o;_iS MAFoo n1*=k control 4Y.^D
!8 Connect
.3N 0qczTMr?.9T uh6;Qfe|
_ `)
2 MainMenu.nib lg
MAFoo >/K,9e<d. Classes BTwr?
.D#9Vb-
MAFoo #>\/K,9U, Classes b
/
Create Files for MAFooe< Interface Builder rPT@(X,9H5v.~
9"
[y]r(^+H5.'Cf9RHxF$
^>'C@9

50

BECOME AN XCODER E 

1 8 4 )?' (GUI) !7

$ MAFoo D/7B

.-6 Xcode-,;-!+*98%3)!C*5 Other


Sources <2='$3!C*@A#
")D -:&!>
 (0 Classes <2=

!C*; .(! Xcode +*

51

BECOME AN XCODER A

b 8 e S%x1Q (GUI) Ch$

2R|W!<b 4 e "42R`Z ;$_Y^;$E [11.1] oKz


yC8/kvPqt<T5@*d9SXC:c= M
MAFoo.hKS}header file:0 ?2R.Cs[78{
_qga:%) [3.5] rQ0% NSObject dS#d)CpIK2RC.K>(
NSObject .C
[3]
/* MAFoo */
#import <Cocoa/Cocoa.h>

// [3.3]

@interface MAFoo : NSObject


{
 IBOutlet id textField; // [3.7]
}
- (IBAction)reset:(id)sender;
- (IBAction)setTo5:(id)sender;
@end

_O<" [3.7] %S#+C outlet"id" ECKB"IB" E Interface BuilderfK_8Gd5h$~Ch$


IBAction [3.93.10] i? void q%,@*qcn!jg\dS[VCB"2
Rh$CJm q MAFoo B4^<yJm[VC!
_ O<4%9S Interface Builder Actions
F2RO<uCK #import <Foundation/Foundation.h> ' Kw [3.3] )CU
FDKj3%x1NQCh$6HDKj%x1NQCh$6
a"2RL b
SXMAFoo.m&2R-lC^<]h$~
[4]
#import "MAFoo.h"
@implementation MAFoo
- (IBAction)reset:(id)sender // [4.5]
{
}

52

BECOME AN XCODER J

h 8 n [+6W (GUI) Lu*

- (IBAction)setTo5:(id)sender
{
}
@end

X!MAFoo.h }i|%,M}E=H/jC}i
A[Ireset: setTo5:ZQ7Z4LIID*S2emU8eL
u*GE
Pz&7ZLu*[OyiO]}{_[^\weL
MAFoo K@U:b.C[I7Z URj=`3 1u*"lU
3L<q+& Interface Builder 3Oy MAFoo KzLkvt-7ZLU
u* MAFoo K{_^\E)0%,7Zr?V [5.75.12]
[5]
#import "MAFoo.h"
@implementation MAFoo
- (IBAction)reset:(id)sender
{
 [textField setIntValue:0]; // [5.7]
}
- (IBAction)setTo5:(id)sender
{
 [textField setIntValue:5]; // [5.12]
}
@end

qeTEL7Z{_[^\w textField outlet FaLK%R7Z >


 Interface Builder 8j[ outlet kvEL)0%,7ZL^\q}i{_w
LKj[^\Q[IL$)setIntValue:[YI setIntValue: 
&)0[Y&n7Zc5xe7ZQ(19Ej[IL
g&e ~o'UeLu*;f`d& Xcode L B#O Build
and Go OypNj[u*}g&-e s

53

BECOME AN XCODER 6 

* 8 + $/ " (GUI) ,

#,'

5
)%%.$(&,) 0!4
,3

21--

54

BECOME AN XCODER O

q 9 v z;7N

q9v
z;7N
)Sv9`ENsaK29`0DaNQ6W9`
a Apple I|AQNsetIntValue: W)+3P"!_QN6Wn[
*5;EsaQNG
h4JnQ=a Apple xtQNnu[%0#5,
.f <>-gbug-free(.)r\n0QNS$R
cXXZWW-/'QNWT_mQ
) Interface Builder *Ln:}ke)]MQP" -a 
CBC*Ln:}ke)V! nZE "NSButton"*Lnke)!Y
''System Font Text" Q+3 nZE "NSTextField"s@=auWa7&
p)9`CZZ NSTextField 7-QN
Xcode)y F Help->Documentation)Q^dF Cocoa U)
z3 "NSTextField"H API-Search ,WFjCQl
]Q
)n QcboyQbL{~T8Qn{ZE NSTextField p)w ]
NSTextField I)Q?17Y ClassC NSTextField 7Qi!)
Q^
d

55

BECOME AN XCODER | <

W 9 \ `-u*;

 Xcode ! Cocoa j8 oz

IPph:e2>CYLu*Cv7(1.>u*!@^BH>C^]r
NSObject Hrn5 QCmt

Method Types
YaC,KGc3`-> +Z>sz fbU,K!Yg- 2,K6kG>
;0!#x)=
{lJEv7>MA,KkGDF NSTextField u*>
?wu*NSControl'"9,KS,KdvyqD>u* NSView
&uRE6%>[C HTML N$6,KkGr {! Inherits from T_
># NSControla{ NSControl u*>iO

NSControl
Inherits from

NSView : NSResponder : NSObject

PF2,K
VLu*!;T_ ,K:e2L mt

Setting the controls value


/C,KG>0X4LlJ!YL mt H,K-2
setIntValue:

56

BECOME AN XCODER Y

9 C>W

~Kh)SBwKnq
[t setIntValue: 
setIntValue:
- (void)setIntValue:(int)anInt
Sets the value of the receivers cell (or selected cell) to
the integer anInt. If the cell is being edited, it aborts all
editing before setting the value; if the cell doesnt inherit
from NSActionCell, it marks the cells interior as needing to
be redisplayed (NSActionCell performs its own updating of
cells).
-Bw[2Bw[ NSTextField Z#l3]7BwrxBw
!xW[|2signatureqK
- Objective-C s"xWf@[Pp[l>WBw
iMvoid ^"+$;U9W[~]jlBwx setIntValue: }z textFieldBw[ MAFood Z#!0:Z#H3M$;[v+
KFa-biu(int) ^" anInt lx-Bw[J 
Bw[lv 5 R 07wlF*6BwM$;
4{yrCM[WK
[S`k

l4A[<lD%#iX.

/Vr0:Z# textField Nv /;O|L2[,l


S4[~KW Z#4p[W
o "1NL2"Accessorsx KNvx KQvBw \
i] l setIntValue: Wc]q~Kd
u
[1]
- (int) intValue

/SGxW+x*6/VrNBw textfield Z#[


vBwrx/
[}z
[2]
resultReceived = [textField intValue];

&5-L2WS4[gT([I
K_*or-2mx%Q[x=M:
T>L2e4p'([x7L2(l[
Objective-C 8DE[gW(r-'x>l[?7

57

BECOME AN XCODER  L

q 9 w y96J

"N6P-X"NJ%uH R,>U_T}Ng&V
,t\b^#06/ C.NJ%pY
-B3H "6 N "JQ-X"N%u'DZs V "(
R" polymorphismuUM$,t\object-oriented programming*.e
6Na&n' [;!OnFNMUH46NoK zg
l jN,['k2|run-timedu_fNMgl
niNhc7u_)rnz't\
?-E-EN
,=>'8^xvN GUI , *I8^@gl setIntValue: h
cN6M>A+38^N,~' `:,W1 ]
NoK m58^W1'k2|G{M/ 4;ouF<
NzUM$,t\NS

58

BECOME AN XCODER "V

10 awakeFromNib

10
awakeFromNib
Apple byu- :y,]&7 X2mrxlQC,yX 2y
!b, _-IBz6j :X
$
HjoaframeworkG3>i,XF [12] X Foundation Kit oa
E
=D#YcgXSvjoab Application Kit\~y
, eJXW'D#Yw<Hjoa4@.XR'
>i+J>iX GUI 2t>i,f>iX2,|wZ5Xmk
&;,08W' %jpLXh
N4jdXs1,j nib nnib [X` Next Interface Builder[%>ifXUr`P Application Kit XI(>ieef/9
?PjoaXsJ Xcode X Help  Documentation
,R'L Full-Text Search)q`|#Xf|# 
8X O
A,XK Full-Text Search{,8 Application Kit ^_ Return Xcode EyjTI4('*b Application Kit Reference for Objective-Cy,I?J(joaNEXSv},
Protocols M4ju NSNibAwakening X

NSNibAwaking
Declared in

AppKit/NSNibLoading.h

Programming Topic

Loading Resources

Contents:
Protocol Description
Method Types
Instance Methods
Protocol Description
This informal protocol consists of a single method, awakeFromNib. Classes can implement this method to perform final initialization of state after objects have been loaded from an
Interface Builder archive.
59

BECOME AN XCODER  B

] 10 c awakeFromNib

#@1Mv-`NAo!1MDCD nib S rR^=


8t;1MD|![WR!$*NL

'1M

1iw oyJ3;~DAG k0(DaXzJ647&QD


$8md U3;DA 'Z) }Y`9NTHDGFXKJ
D`{Z oEsZ7P6.xAZ>_ oRR::bzJ,G
o</Z3J#+ZDf%V;ZJ-D5
"\!1M
q3;1MJDA1M?zJ-De&2`NA1MDv MAFoo.m [1.15] 
[1]
#import "MAFoo.h"
@implementation MAFoo
- (IBAction)reset:(id)sender
{
[textField setIntValue:0];
}
- (IBAction)setTo5:(id)sender
{
[textField setIntValue:5];
}
- (void)awakeFromNib // [1.15]
{
[textField setIntValue:0];
}
@end

pjgl[DROawakeFromNib Ao^)W=h@pZI;`NnlDjg
R$*ou

60

BECOME AN XCODER

Z

11 h

11
h
9v:[QFP[ C DQ|L_^
*X(<#Y !
}2D - hpointer*
56f/8 - VN! Objective-C J3-qF i[
Ovg[ Mac >v~[jG]J
,v[t
IJk [r
[1]
int x = 4;

lp3[ Mac ([~?GC/H![]gW


]i x [tU,['=u( H!K[%
$n0h [1]Wv[d7(i int[\(~
p)[]J, x [t2*Xvt[d7i long long S doubleEpb{[
~@)
vhOh "x = 4" >+ 4 ,(vb{[][~v%l x
[t,(~[5S^\ x [4;addressl5*
1JA0([-H! x [yw[kn ['( [4
;g?L x [t
vhpointeriv:/K4;[
v(csv & JM[4;IJpM x [4
;p. &x
-expressionx Btevaluate[yw& x [t(=u[I
& 4m[- &x Bty& x [4;2a,
V1[t4;iv`"~zO4[+T`"(xzO
[T
 se9vh
[2]
int *y;

vrOv%l y [:/vd7l int [[4;p( y 


, x [4; -[RohO x [4; yp6
61

BECOME AN XCODER `


0

G 11 J 4\

[3]
y = &x;

N=4\E I=4\2Y6Q(*D,41_Z'TI=U
*y

$<PO 4IVTU "x" $<9MCI=4


*y = 5

VC4 "x = 5" 59M1


4\518@>E%:7R_Z1<5:1 "^'(W/E:
H;=)(T_Z 1EX:OBNI=_Z1 "I58E5:?#]
_Z1.5KA1&21_Z<E:&=4\(!8 Z
[4]
void increment(int *y)
{
 *y = *y + 1;
}

L3E SI[+
[5]
int x = 4;
increment(&x);
// F x M- 5 

62

BECOME AN XCODER %Y

12 3<

12
3<
P(_gDmhP s`@integerlong]floatu
doublekbuBOOL#X+ Dm[ pointere
Dm_~P3<stringnt 70P NSLog() O5[toP
KnO5Dm,-n3<P  &nlN % [v
@M2 %d
[1]
float piValue = 3.1416;
NSLog(@"Here are three examples of strings printed to the screen.\n");
NSLog(@"Pi approximates %10.4f.\n", piValue);
NSLog(@"The number of eyes of a dice is %d.\n", 6);

Dm_JG7E3<?gns`@N}y/g7nd1['"mfZ*f'
NSString @T NSMutableString @Uc)[0DmN}yK@' NSString
R
[2]
NSString *favoriteComputer;
favoriteComputer = @"Mac!";
NSLog(favoriteComputer);

|w
nj!fdrV[>f! [2.1] iK x{
DmaAnetDm$Wnee.[fps`@S f 11
[2] [j!
[3]
int *y;

DmAne y B7FPn[x=C0 [2.1] DmA


ne favoriteComputer B7FPn`@g NSString [Z*[x=
CDmL&eN^4Dm[3</g0 Objective-C Z*\~
:f'e."m[eNP
1gn7[ @ 9fQIf/g Objective-C fn C H[
: C H7";q3<[5> Objective-C [n3<`@fn
6[Z*/8g 7Uz@Objective-C L& @ n

63

BECOME AN XCODER %W

y 12  4;

I Objective-C S4;cS C GE jPObjective-C 4;` Unicoder4;9\ ASCII 4;Unicode 4;(+=GY4


N33.q4&
 .lbh4;]BJZQ_ [4]
[4]
NSString *favoriteActress = @"Julia";

}h_ favoriteActress _/oYah<9}h<`'O[( "Julia" }


h4;X*R5Y1
#tZQ }h)A favoriteComputert}h hf>`
tUE}h4;$H [5]0b"`h NSString @YDg8,v

L
[5]
#import <Foundation/Foundation.h>
int main (int argc, const char *argv[])
{
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 NSString *x;
 x = @"iBook";

// [5.7]

 x = @"MacBook Pro Intel"; // D!`}$mdpOnY l 


 NSLog(x);
 [pool release];
 return 0;
}

s:^}h6-
MacBook Pro Intel

h NSString @Y4;|bEYimmutable0b"n|iE
tniE4;72{P?FzOniEY4;kT{wR
tY6YCK tM' Objective-C OtY6ltx~
YuV tJeiEtY4;

64

BECOME AN XCODER Q

s 12 x /8

{3gbpX]cAS/8*43;5pNU"S/
8R$TXcASva]JS;X NSMutableString ;>`,x|Vm
iJ_%>`LpSJ/8XaR$W{`XR$>`y
kjf~`GH>`k length jf~a/8R$ [6]
[6]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 int theLength;
 NSString * foo;
 foo = @"Julia!";
 theLength

= [foo length];

// [6.10]

 NSLog(@"The length is %d.", theLength);


 [pool release];
 return 0;
}

l7Vva}0&
The length is 6.

]EqSgb}0u^egnF foo bar :Z)E `XS)/*Z`C3y x >`,v(pt`Vp,


Si\J`gyoKM
,s [6.10] 7>`( foo R$kjf lengthvajf length XL, NSString ;
.N!
- (unsigned int)length
Returns the number of Unicode characters in the receiver.
ph
]?/8S/1 [7]Zva SmSjf#<
uppercaseStringk~va/8R$p,O$6 @JY
NSString ;FSPr2Jvajfva/8R$U"D+a
S/8R$I=['Sd9XBa/w z1[S /
[7]

65

BECOME AN XCODER Q -

C 12 E 

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSString *foo, *bar;
 foo = @"Julia!";
 bar

= [foo uppercaseString];

 NSLog(@"%@ is converted into %@.", foo, bar);


 [pool release];
 return 0;
}

> 5D8GL
Julia! is converted into JULIA!

<9?=LJ7:%8B /
;348K/DM@,?H&
NSMutableString P"/.)1?/ NSMutableString F'OM +)R?:%
 /
;(appendString: D8 +L$!6 OI/ 2*A0/#N
[8]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSMutableString *foo;

// [8.7]

 foo = [@"Julia!" mutableCopy];

// [8.8]

 [foo appendString:@" I am happy"];


 NSLog(@"Here is the result: %@.",

foo);

 [pool release];
 return 0;
}

> 5D8GL
66

BECOME AN XCODER  H

k 12 s (.

Here is the result: Julia! I am happy.

%k [8.8] -F mutableCopy NSString 2Dv=O:}$Zi)L*U


![J9mutable(.oM%k [8.8] -d-Pfoo ~Q"Z9
J(.I ,4*(. "Julia!"
%sNW7Y % Objective-C I y ~Kim,SQ"Y
JQouST7Y% WJ [8.7] -<Ql; 7Y% ObjectiveC < "I " oZ{^7YQJpeS "Q"ZI JQ"0SRw7YSq
Q?<I 7Yu8T "I ",I SqQ?<JoZj *
Zf|VJt%@ Z!^c+A!ZI >?%d6k [8.7] -P foo c+AZ?M(. "Julia!" JI 7YWJ
?M
Z#T "foo" J
4*Z(
.I J/5

Z(.I

SqQ?hB

j%an7YWo8 foo JXQCz bar


bar = foo;

oZb1JxEuSj% foo bar rQ"!ZI


Z#T "foo" J
4*Z(.
I J/5

Z(.I

Z#T "bar" J
4*Z(.
I J/5

&ZcA!ZI

%ogG< foo 1Ti)L?}`Z_\zI 3 [foo dosomething];


< bar ?}`_\3 [bar dosomething];*U!J]Eu'WoZ>
D

[9]
#import <Foundation/Foundation.h>

67

BECOME AN XCODER F %

5 12 7 

int main (int argc, const char * argv[])


{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSMutableString *foo = [@"Julia!" mutableCopy];
 NSMutableString *bar = foo;
 NSLog(@"foo points to the string: %@.",

foo);

 NSLog(@"bar points to the string: %@.",

bar);

 NSLog(@"------------------------------");
 [foo appendString:@" I am happy"];
 NSLog(@"foo points to the string: %@.",

foo);

 NSLog(@"bar points to the string: %@.",

bar);

 [pool release];
 return 0;
}

2
)6-9; 
foo points to the string: Julia!
bar points to the string: Julia!
-----------------------------foo points to the string: Julia! I am happy
bar points to the string: Julia! I am happy

03.' 1<#-&A&D9B!C+-$/'0
@,
('7=8>?6-0E !C5 8 7,84"-
'*:&1<#,' MAFoo &

68

BECOME AN XCODER #e

13 +

13
+
8|v[P+gWXv?g4?3L
{4?,<U${88{mgN+
array+r{8Ggf*?+ajKg r{f*qg?+
If* Z+%+f*ajvM{+h50s{
@index)Dq^g@gr{f*9vM+h F8
1{element
c>g|% 1 ]A0+{&gr
{gr
1T9

{4?

{4?
{4?
W{F8 {4?g+

Hz0"pS6W %]wg
+r%Y{CbVNSArray  NSMutableArray4?8}J
}Jge"0"Hz:}Jg{e"
{o(+gdr= yg6
[NSMutableArray array]

=p=6o(Q/{ig+Ar {62``g
rg0{WHzU$ { NSMutableArray Cg-XBtg
7jArHzv;lCOE
Hz~~Z {c>R0 Objective-C HzC
;.rCrf* zrHzt meta-classes gHz0
K g{_0 Cocoa *Hz0C\gdr
"+" Xk';lHz!0d-nyuZg "-" W3 8 [4.5]WX
0*HzuZ{ array dgx

array
+ (id)array
69

BECOME AN XCODER H #

5 13 7 1

Creates and returns an empty array. This method is used by mutable subclasses of NSArray.

See Also: + arrayWithObject:, + arrayWithObjects:


I->F A@9E,$9;'.%$18(=,G.
4:6.1$
/.B
[1]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSMutableArray *myArray = [NSMutableArray array];
 [myArray addObject:@"first string"];
 [myArray addObject:@"second string"];
 [myArray addObject:@"third string"];
 int count = [myArray count];
 NSLog(@"There are %d elements in my array", count);
 [pool release];
 return 0;
}

2 (6.9;
There are 3 elements in my array

,$9?&.DC) $)1G0 <* 0 $+!


36. objectAtIndex: 6. " [2.13]
[2]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{

70

BECOME AN XCODER >




1 13 4 *

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


 NSMutableArray *myArray = [NSMutableArray array];
 [myArray addObject:@"first string"];
 [myArray addObject:@"second string"];
 [myArray addObject:@"third string"];
 NSString *element = [myArray objectAtIndex:0];

// [2.13]

 NSLog(@"The element at index 0 in the array is: %@", element);


 [pool release];
 return 0;
}

-!3%56 
The element at index 0 in the array is: first string

/8.6<#2%*;* %'+0#+3%&/ :
$3%"7(  *' 5=),9
[3]
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSMutableArray *myArray = [NSMutableArray array];
 [myArray addObject:@"first string"];
 [myArray addObject:@"second string"];
 [myArray addObject:@"third string"];
 int i;
 int count;

71

BECOME AN XCODER &b

13 -

 for (i = 0, count = [myArray count]; i < count; i = i + 1)


 {
  NSString *element = [myArray objectAtIndex:i];
  NSLog(@"The element at index %d in the array is: %@", i, element);
 }
 [pool release];
 return 0;
}

=mz7.
The element at index 0 in the array is: first string
The element at index 1 in the array is: second string
The element at index 2 in the array is: third string

`-M!wY]n95>#yn9,@uec+
NSArray NSMutableArray CP3Tea;Hy qN
Ce_+QJ3]-efHyz'zc+Q
replace z?]pz?c+eaM:r%
"za
X0r replaceObjectAtIndex:withObject:U)lrHy!39z
eaAoz/; or@Hyu2s#e{1#VRz
(#0[FeRzk;Q2 Objective-C a9,
e
ou4@O'zaea
[4]
[myArray replaceObjectAtIndex:1 withObject:@"Hello"];

=zam?] 1 ec+o5> @"Hello"za!


z9}validexQ o$9zc+62Hyz
ae?4:Qza'Hy#ec+2-=e
B4[K2 Objective-C ea0z9gket
" uza~uI&exNg;G8zS9
e "" "z'Qh*a0=aeao\< Smalltalk# o
Objective-C e1r#7iS9h expressive<
ea~ E e "#yW~G8z9h e" " r)
Qr#yX09D] Objective-C 7S9Z]e7jn2
|^ed;Loivue

72

BECOME AN XCODER $`

14 

14

23I0pL;SbnQv!>NQv!m'Tb
b8Om Mac b8> RAM myqb0=5^b8.
tn,bJ"Mb% Ht;Od
Xor{4$m2lu8GRb8m2@b8[
freeb8
>b 9
b8i)ya*{ya*2C'Qe>#2.R'
ya*j[e"bkmba*.R'j|
destroy">tEya*{j.R'~Og]PS
T28b@ba*~3Uba*Z0= t;Ua
*~R'V""~|R'y|ba*~sb
8Y&_b@p
pWF2a*.tb{z|"xCocoa Jyu
Kya*
"fa*Zb "h}"retain count2b86yna*b
{#Jya*bh}T"c*Prbyn
a*b{#Jya*bh}Tc"ya*bh}\
{ya*c".+B1ZO7-b|ya*
|"?O[rb
STb8myA>;D'Tf(:[/fba*
2;ny:a* y[/fa*V5^"L;.Ub1V
b:a*;y\ bh}

[/f
1

w:
h} =
3

[/f
2

[/f
3

ya*c"<>t\"bh}

73

BECOME AN XCODER !R

y 14 ox

chS'TYmvcqh retain phS'5chS'


TYmv cqh release pjhS'Cocoa E h_ "autorelease pool"1sO/TIvqhLT release pjhS' - ^&
50^\cD"vc;hS'HNT autorelease pool ^#
qh autorelease pjvTS'F,autorelease pool eqhLT release
pjvTS'AC9g)ZT+aH autorelease pool .Tf^9g_
c!T~K autorelease pool I0?zT]
h_ Cocoa ND" ^9g) N{Tox:|n}_ reference countingtdv)=TlMt@y 15 <H Cocoa ox?z
T8QC Apple iX% Apple !)_ Cocoa 3hTox
+_ automatic garbage collection1sJ7-h+$ZT=u P"0
P0) lkApple B>.2kMU^68,BEb:r
(2Y
Apple ) 2006 *T WWDC World Wide Developer Conference`U

[4) 2007 *V4 Xcode 3.0 kGWw" automatic garbage collection :
|T Objective-C 2.0

74

BECOME AN XCODER *k

15 =

15
=
)l.{5 Xcode  Objective-C l7i)]<
X?RY[W67C*xl
,)Vlm\NlFh`
6H,_ l> flYs{jl
5bl9r;lv bc0~
}4 Apple $M:EenZ%lR3
SlG2l| $M:lSXPbZ"\f0~
/X\?ll{ Apple lnAg
http://www.apple.com/developer

OlvP 1#

http://osx.hyperjeff.net/reference/CocoaArticles.php
http://www.cocoadev.com
http://www.cocoabuilder.com
http://www.stepwise.com

lL;`_

\l5
http://lists.apple.com/mailman/listinfo/cocoa-dev cocoa-dev l/1p
mailing list5$lll \aI
lqzX0{J$5u8http://www.cocoabuilder.comQ`
l   Y g 5 / 1 p  l v  U A g
http://www.catb.org/~esr/faqs/smart-questions.html l "How To Ask Questions The
Smart Way"k "l" Ag h t t p : / / m i s . n d h u . e d u . t w / d o c u /
question.htm
' ;Yg Cocoa l6Stephen Kochan l Programming in Objective-C {
onl;Y^-)f`lmOw-B5
Big Nerd Ranch l Aaron Hillegass fl Cocoa Programming for Mac OS X 5W
Xcode +Ow- James Duncan Davidson Apple 3 O'Reilly @l Cocoa
with Objective-C
yKl{{5 Mac 95"l9rq&D{T
;l>&\wXdg Apple &Ag
http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuid
elines/index.html>(M:&gPl9"\_

lv

aIX!l9Xz5t 
75

BECOME AN XCODER )

 15

 $

!('
Xcode # "& % 0

Bert, Alex, Philippe.

76

You might also like