์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ์Šค์œ„ํ”„ํŠธ vs ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C: ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์™€ ARC์˜ ํšจ์œจ์„ฑ ๋Œ€ํƒํ—˜! ๐Ÿง 

๐Ÿš€ ์Šค์œ„ํ”„ํŠธ vs ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C: ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์™€ ARC์˜ ํšจ์œจ์„ฑ ๋Œ€ํƒํ—˜! ๐Ÿง 

์•ˆ๋…•, ์นœ๊ตฌ๋“ค! ์˜ค๋Š˜์€ ์ •๋ง ํฅ๋ฏธ์ง„์ง„ํ•œ ์ฃผ์ œ๋กœ ์šฐ๋ฆฌ ํ•จ๊ป˜ iOS ๊ฐœ๋ฐœ์˜ ์„ธ๊ณ„๋กœ ๋– ๋‚˜๋ณผ ๊ฑฐ์•ผ. ๋ฐ”๋กœ ์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฐฉ์‹์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ๊ฑฐ๋“ . ํŠนํžˆ ARC(Automatic Reference Counting)๋ผ๋Š” ๋…€์„์ด ์–ด๋–ป๊ฒŒ ์ด ๋‘ ์–ธ์–ด์—์„œ ํšจ์œจ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ ๊ฑฐ์•ผ. ์ค€๋น„๋๋‹ˆ? ๊ทธ๋Ÿผ ์ถœ๋ฐœ~! ๐Ÿ

๐Ÿ” ์ž ๊น! ์•Œ๊ณ  ๊ฐ€์ž! ์ด ๊ธ€์€ '์žฌ๋Šฅ๋„ท'์˜ '์ง€์‹์ธ์˜ ์ˆฒ' ๋ฉ”๋‰ด์— ๋“ฑ๋ก๋  ์˜ˆ์ •์ด์•ผ. ์žฌ๋Šฅ๋„ท์€ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•˜๋Š” ํ”Œ๋žซํผ์ธ๋ฐ, ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šฐ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ง€์‹๋„ ์ถฉ๋ถ„ํžˆ ์žฌ๋Šฅ์ด ๋  ์ˆ˜ ์žˆ์ง€. ์–ด์ฉŒ๋ฉด ๋‚˜์ค‘์— ๋„ˆ๋„ iOS ๊ฐœ๋ฐœ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์„์ง€๋„ ๋ชฐ๋ผ!

๐Ÿ“š Chapter 1: ์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C, ๋ˆ„๊ตฌ์•ผ ๋„Œ? ๐Ÿค”

์ž, ์šฐ๋ฆฌ์˜ ์ฃผ์ธ๊ณต๋“ค์„ ๋จผ์ € ์†Œ๊ฐœํ• ๊ฒŒ. ํ•œ ์ฝ”๋„ˆ์—๋Š” ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C, ๋‹ค๋ฅธ ์ฝ”๋„ˆ์—๋Š” ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์žˆ์–ด. ์ด ๋‘˜์€ ๋งˆ์น˜ ํ˜•์ œ์ฒ˜๋Ÿผ iOS ๊ฐœ๋ฐœ์˜ ์ค‘์‹ฌ์— ์„œ ์žˆ์ง€.

๐Ÿ•ฐ๏ธ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C: ๊ณ ์ „์˜ ๋ฏธํ•™

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋Š” ๋งˆ์น˜ ์šฐ๋ฆฌ ํ• ์•„๋ฒ„์ง€ ๊ฐ™์€ ์กด์žฌ์•ผ. 1983๋…„์— ํƒœ์–ด๋‚ฌ์œผ๋‹ˆ๊นŒ ์ •๋ง ์˜ค๋ž˜๋์ง€? ํ•˜์ง€๋งŒ ๋‚˜์ด๊ฐ€ ๋งŽ๋‹ค๊ณ  ๋ฌด์‹œํ•˜๋ฉด ์•ˆ ๋ผ. ์ด ๋…€์„, ์•„์ง๋„ ๋งŽ์€ iOS ์•ฑ์˜ ๊ธฐ๋ฐ˜์ด ๋˜๊ณ  ์žˆ๊ฑฐ๋“ .

  • C ์–ธ์–ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ์–ด
  • ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง€์›ํ•ด
  • ๋™์  ํƒ€์ดํ•‘์ด ๊ฐ€๋Šฅํ•ด (๋Ÿฐํƒ€์ž„์— ํƒ€์ž… ๊ฒฐ์ •)
  • ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ”๋กœ '๊ด„ํ˜ธ ์‚ฌ๋ž‘'์ด์•ผ. ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๊ด„ํ˜ธ๊ฐ€ ์ •๋ง ๋งŽ์ด ๋ณด์ผ ๊ฑฐ์•ผ. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ?


NSString *greeting = [[NSString alloc] initWithString:@"์•ˆ๋…•, ๋‚˜๋Š” ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์•ผ!"];
NSLog(@"%@", greeting);

์–ด๋•Œ? ๊ด„ํ˜ธ๊ฐ€ ๊ฝค ๋งŽ์ง€? ์ด๊ฒŒ ๋ฐ”๋กœ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๋งค๋ ฅ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์–ด. ๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ, ์ด ๊ตฌ์กฐ๊ฐ€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฑฐ์ง€.

๐ŸŒŸ ์Šค์œ„ํ”„ํŠธ: ๋ชจ๋˜ํ•œ ์‹ ์˜ˆ

๋ฐ˜๋ฉด์— ์Šค์œ„ํ”„ํŠธ๋Š” ์šฐ๋ฆฌ์˜ ํž™ํ•œ ์‚ฌ์ดŒ ๊ฐ™์€ ์กด์žฌ์•ผ. 2014๋…„์— ์• ํ”Œ์ด ์„ ๋ณด์ธ ์ด ์–ธ์–ด๋Š” ํ˜„๋Œ€์ ์ด๊ณ  ์•ˆ์ „ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง€ํ–ฅํ•ด.

  • ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฌ์šด ๋ฌธ๋ฒ•
  • ํƒ€์ž… ์•ˆ์ „์„ฑ (์ปดํŒŒ์ผ ์‹œ์ ์— ํƒ€์ž… ์ฒดํฌ)
  • ์„ฑ๋Šฅ ์ตœ์ ํ™”
  • playground ๊ธฐ๋Šฅ์œผ๋กœ ์ฝ”๋“œ ์‹คํ—˜์ด ์‰ฌ์›Œ

์Šค์œ„ํ”„ํŠธ๋Š” '์‹ฌํ”Œํ•จ'์„ ์ถ”๊ตฌํ•ด. ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์Šค์œ„ํ”„ํŠธ๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ๋ณ€ํ•ด:


let greeting = "์•ˆ๋…•, ๋‚˜๋Š” ์Šค์œ„ํ”„ํŠธ์•ผ!"
print(greeting)

์–ด๋•Œ? ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜์ง€? ์ด๊ฒŒ ๋ฐ”๋กœ ์Šค์œ„ํ”„ํŠธ์˜ ๋งค๋ ฅ์ด์•ผ. ์ฝ๊ธฐ ์‰ฝ๊ณ , ์“ฐ๊ธฐ๋„ ์‰ฝ์ง€.

๐Ÿ’ก ์žฌ๋Šฅ๋„ท Tip! ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ฒƒ๋„ ํ•˜๋‚˜์˜ ์žฌ๋Šฅ์ด์•ผ. ์žฌ๋Šฅ๋„ท์—์„œ๋Š” ์ด๋Ÿฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํ‚ฌ์„ ๊ณต์œ ํ•˜๊ณ  ๊ฑฐ๋ž˜ํ•  ์ˆ˜ ์žˆ์–ด. ์Šค์œ„ํ”„ํŠธ๋‚˜ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋ฅผ ๋งˆ์Šคํ„ฐํ•˜๋ฉด, ๋„ˆ๋„ ์žฌ๋Šฅ ํŒ๋งค์ž๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ!

๐Ÿง  Chapter 2: ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ, ์™œ ์ค‘์š”ํ• ๊นŒ? ๐Ÿค”

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ์ฃผ์ธ๊ณต๋“ค์„ ๋งŒ๋‚ฌ์œผ๋‹ˆ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์–˜๊ธฐํ•ด๋ณผ๊นŒ? ๊ทผ๋ฐ ์ž ๊น, ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ๋ญ๊ธธ๋ž˜ ์ด๋ ‡๊ฒŒ ์ค‘์š”ํ•œ ๊ฑธ๊นŒ?

๐Ÿ  ๋ฉ”๋ชจ๋ฆฌ, ์šฐ๋ฆฌ ์ง‘ ๊ฐ™์€ ์กด์žฌ

๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์šฐ๋ฆฌ ์ง‘์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž. ์ง‘์— ๋ฌผ๊ฑด์„ ๋“ค์—ฌ๋†“์„ ๋•Œ๋งˆ๋‹ค ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜์ง€? ํ”„๋กœ๊ทธ๋žจ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์•ผ. ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ , ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋ฉ”๋ชจ๋ฆฌ๋ผ๋Š” '์ง‘'์— ๋ญ”๊ฐ€๋ฅผ ๋“ค์—ฌ๋†“๋Š” ๊ฑฐ์•ผ.

๊ทผ๋ฐ ๋งŒ์•ฝ ์ง‘์— ๋ฌผ๊ฑด๋งŒ ๋“ค์—ฌ๋†“๊ณ  ์ ˆ๋Œ€ ์น˜์šฐ์ง€ ์•Š๋Š”๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ๋งž์•„, ๊ฒฐ๊ตญ ์ง‘์ด ๋ฌผ๊ฑด์œผ๋กœ ๊ฐ€๋“ ์ฐจ์„œ ๋ฐœ ๋””๋”œ ํ‹ˆ๋„ ์—†๊ฒŒ ๋˜๊ฒ ์ง€. ํ”„๋กœ๊ทธ๋žจ๋„ ๋˜‘๊ฐ™์•„. ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ œ๋Œ€๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๋А๋ ค์ง€๊ฑฐ๋‚˜ ์ตœ์•…์˜ ๊ฒฝ์šฐ ํฌ๋ž˜์‹œ๊ฐ€ ๋‚  ์ˆ˜๋„ ์žˆ์–ด.

๐Ÿšฎ ์“ฐ๋ ˆ๊ธฐ ์ˆ˜๊ฑฐ์˜ ์ค‘์š”์„ฑ

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” '์“ฐ๋ ˆ๊ธฐ ์ˆ˜๊ฑฐ'๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ–ˆ์–ด. ์‹ค์ œ ์ƒํ™œ์—์„œ๋„ ์“ฐ๋ ˆ๊ธฐ๋ฅผ ์ œ๋•Œ ๋ฒ„๋ฆฌ์ง€ ์•Š์œผ๋ฉด ์ง‘์•ˆ์ด ์—‰๋ง์ด ๋˜์ž–์•„? ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์•ผ.

  • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€: ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณ„์† ์ฐจ์ง€ํ•˜๋Š” ๊ฑธ ๋ง‰์•„์ค˜
  • ์„ฑ๋Šฅ ํ–ฅ์ƒ: ํ•„์š” ์—†๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ฆฌํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๋” ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•ด
  • ์•ˆ์ •์„ฑ ์ฆ๊ฐ€: ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ž˜ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์˜ˆ์ƒ์น˜ ๋ชปํ•˜๊ฒŒ ์ข…๋ฃŒ๋˜๋Š” ์ผ์„ ์ค„์ผ ์ˆ˜ ์žˆ์–ด

๐ŸŒฑ ํ™˜๊ฒฝ ๋ณดํ˜ธ Tip! ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ๋งˆ์น˜ ์žฌํ™œ์šฉ๊ณผ ๋น„์Šทํ•ด. ๋” ์ด์ƒ ํ•„์š” ์—†๋Š” ์ž์›์„ ํšจ์œจ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ์ง€. ์ด๋Ÿฐ ๋งˆ์ธ๋“œ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‹ค์ œ ์ƒํ™œ์—์„œ๋„ ์ค‘์š”ํ•ด. ์žฌ๋Šฅ๋„ท์—์„œ๋„ ์ด๋Ÿฐ '์ž์› ํšจ์œจ์„ฑ'์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ๊ณต์œ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„!

๐Ÿ‘ฅ ์ฐธ์กฐ ์นด์šดํŒ…: ์ธ๊ธฐ ํˆฌํ‘œํ•˜๊ธฐ

์ž, ์ด์ œ ์ฐธ์กฐ ์นด์šดํŒ…์ด๋ผ๋Š” ๊ฐœ๋…์„ ์†Œ๊ฐœํ• ๊ฒŒ. ์ด๊ฑด ๋งˆ์น˜ ์ธ๊ธฐ ํˆฌํ‘œ์™€ ๋น„์Šทํ•ด. ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ 'ํŒฌ'์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ์„ธ๋Š” ๊ฑฐ์•ผ.

๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค ์นด์šดํ„ฐ๊ฐ€ 1 ์ฆ๊ฐ€ํ•˜๊ณ , ๋ˆ„๊ตฐ๊ฐ€ ๊ทธ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์นด์šดํ„ฐ๊ฐ€ ๋˜ ์ฆ๊ฐ€ํ•ด. ๋ฐ˜๋Œ€๋กœ ๋ˆ„๊ตฐ๊ฐ€ ๊ทธ ๊ฐ์ฒด๋ฅผ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒ ๋‹ค๊ณ  ํ•˜๋ฉด ์นด์šดํ„ฐ๊ฐ€ 1 ๊ฐ์†Œํ•ด. ์นด์šดํ„ฐ๊ฐ€ 0์ด ๋˜๋ฉด? ๊ทธ๋•Œ ๊ทธ ๊ฐ์ฒด๋Š” "์•„, ๋‚˜๋ฅผ ์•„๋ฌด๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๊ตฌ๋‚˜"๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ณ  ์Šค์Šค๋กœ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ฌ๋ผ์ ธ.

์ฐธ์กฐ ์นด์šดํŒ… (ARC) ๊ฐœ๋…๋„ ์นด์šดํŠธ: 3 ์ฐธ์กฐ 1 ์ฐธ์กฐ 2 ์ฐธ์กฐ 3 ๊ฐ์ฒด ARC ์นด์šดํŠธ 0 1 2 3

์ด ๊ทธ๋ฆผ์„ ๋ณด๋ฉด, ํ•˜๋‚˜์˜ ๊ฐ์ฒด(์ฃผํ™ฉ์ƒ‰ ์›)๊ฐ€ ์„ธ ๊ฐœ์˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๋‚˜ ๋ณ€์ˆ˜(์ดˆ๋ก์ƒ‰ ์›)์— ์˜ํ•ด ์ฐธ์กฐ๋˜๊ณ  ์žˆ์–ด. ๊ทธ๋ž˜์„œ ์ด ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ๋Š” 3์ด ๋˜๋Š” ๊ฑฐ์ง€.

๐Ÿค– ์ˆ˜๋™ vs ์ž๋™: ๋กœ๋ด‡ ์ฒญ์†Œ๊ธฐ์˜ ๋“ฑ์žฅ

์˜ˆ์ „์—๋Š” ์ด ๋ชจ๋“  ๊ณผ์ •์„ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์•ผ ํ–ˆ์–ด. ๋งˆ์น˜ ์ง‘ ์ฒญ์†Œ๋ฅผ ์ผ์ผ์ด ์†์œผ๋กœ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์•ผ. ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€? ๋กœ๋ด‡ ์ฒญ์†Œ๊ธฐ๊ฐ€ ์žˆ์ž–์•„!

ARC(Automatic Reference Counting)๊ฐ€ ๋ฐ”๋กœ ์šฐ๋ฆฌ์˜ ๋กœ๋ด‡ ์ฒญ์†Œ๊ธฐ์•ผ. ์ด ๋…€์„์ด ์ž๋™์œผ๋กœ ์ฐธ์กฐ ์นด์šดํŒ…์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ฑฐ์ง€. ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ๋” ์ค‘์š”ํ•œ ์ผ(์ฆ‰, ์•ฑ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ)์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์–ด.

๐ŸŽ“ ํ•™์Šต Tip! ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ๋ณต์žกํ•œ ์ฃผ์ œ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์ดํ•ดํ•˜๊ณ  ๋‚˜๋ฉด ์ •๋ง ์žฌ๋ฏธ์žˆ์–ด์ ธ. ์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ๊ฐœ๋…์„ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋Š” ํŠœํ„ฐ๋ฅผ ์ฐพ์•„๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ. ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ์ด ๊ฐœ๋…์„ ๊ฐ€๋ฅด์น˜๋‹ค ๋ณด๋ฉด, ๋„ค ์‹ค๋ ฅ๋„ ํ•จ๊ป˜ ๋Š˜์–ด๋‚  ๊ฑฐ์•ผ!

๐Ÿ‹๏ธโ€โ™‚๏ธ Chapter 3: ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ - ๊ณ ์ „์˜ ํž˜ ๐Ÿ’ช

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ 'ํ• ์•„๋ฒ„์ง€' ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š”์ง€ ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ณผ ์‹œ๊ฐ„์ด์•ผ. ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋Š” ์˜ค๋ž˜๋œ ์–ธ์–ด์ง€๋งŒ, ๊ทธ๋งŒํผ ๊นŠ์ด ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฐฉ์‹์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด.

๐Ÿ•ฐ๏ธ ์ˆ˜๋™ ์ฐธ์กฐ ์นด์šดํŒ…์˜ ์‹œ๋Œ€

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋Š” ์ฒ˜์Œ์— ์ˆ˜๋™ ์ฐธ์กฐ ์นด์šดํŒ… ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์–ด. ์ด๊ฑด ๋งˆ์น˜ ์ง‘์•ˆ ์ฒญ์†Œ๋ฅผ ๋ชจ๋‘ ์†์œผ๋กœ ์ง์ ‘ ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ด. ํž˜๋“ค์ง€๋งŒ, ๊ตฌ์„๊ตฌ์„ ๊ผผ๊ผผํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€.

ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ retain(์œ ์ง€)๊ณผ release(ํ•ด์ œ)๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์„ ๊ด€๋ฆฌํ–ˆ์–ด. ์ด๋ ‡๊ฒŒ ๋ง์ด์•ผ:


NSString *myString = [[NSString alloc] initWithString:@"Hello, Objective-C!"];
[myString retain];  // ์ฐธ์กฐ ์นด์šดํŠธ ์ฆ๊ฐ€
// ์—ฌ๊ธฐ์„œ myString ์‚ฌ์šฉ
[myString release];  // ์ฐธ์กฐ ์นด์šดํŠธ ๊ฐ์†Œ

์ด ๋ฐฉ์‹์˜ ์žฅ๋‹จ์ ์„ ํ•œ๋ฒˆ ์‚ดํŽด๋ณผ๊นŒ?

  • ๐Ÿ‘ ์žฅ์ :
    • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ •ํ™•ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์–ด
    • ๊ฐ์ฒด์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์ง€
  • ๐Ÿ‘Ž ๋‹จ์ :
    • ์‹ค์ˆ˜๋กœ release๋ฅผ ๋นผ๋จน์œผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•ด
    • ์ด๋ฏธ ํ•ด์ œ๋œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํฌ๋ž˜์‹œ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ์–ด
    • ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์›Œ์ ธ

๐Ÿง  Autorelease Pool: ์ง€์—ฐ๋œ ์ฒญ์†Œ

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋Š” ๋‚˜์ค‘์— 'Autorelease Pool'์ด๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ–ˆ์–ด. ์ด๊ฑด ๋งˆ์น˜ "๋‚˜์ค‘์— ์น˜์šธ๊ฒŒ~"๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ด.

๊ฐ์ฒด๋ฅผ autorelease ํ•˜๋ฉด, ๊ทธ ๊ฐ์ฒด๋Š” ํ˜„์žฌ์˜ Autorelease Pool์ด drain(๋น„์šฐ๊ธฐ)๋  ๋•Œ๊นŒ์ง€ ๋ฉ”๋ชจ๋ฆฌ์— ๋‚จ์•„์žˆ์–ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ์ฆ‰์‹œ ํ•ด์ œํ•˜์ง€ ์•Š๊ณ ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€.


NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease];
// myString ์‚ฌ์šฉ
[pool drain];  // ์—ฌ๊ธฐ์„œ myString์ด ํ•ด์ œ๋ผ
Autorelease Pool ๋‹ค์ด์–ด๊ทธ๋žจ Autorelease Pool ๊ฐ์ฒด 1 ๊ฐ์ฒด 2 ๊ฐ์ฒด 3 Pool Drain

์ด ๊ทธ๋ฆผ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, Autorelease Pool ์•ˆ์˜ ๊ฐ์ฒด๋“ค์€ Pool์ด drain๋  ๋•Œ๊นŒ์ง€ ์‚ด์•„์žˆ์–ด. ๊ทธ๋ฆฌ๊ณ  drain๋˜๋Š” ์ˆœ๊ฐ„ ๋ชจ๋‘ ํ•œ๊บผ๋ฒˆ์— ํ•ด์ œ๋˜๋Š” ๊ฑฐ์ง€.

๐ŸŒŸ ARC์˜ ๋“ฑ์žฅ: ๋ฐ˜์ž๋™ ์ฒญ์†Œ๊ธฐ

๊ทธ๋ฆฌ๊ณ  ๋งˆ์นจ๋‚ด, ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—๋„ ARC(Automatic Reference Counting)๊ฐ€ ๋„์ž…๋์–ด. ์ด๊ฑด ๋งˆ์น˜ ๋ฐ˜์ž๋™ ์ฒญ์†Œ๊ธฐ๋ฅผ ์–ป์€ ๊ฒƒ๊ณผ ๊ฐ™์•„.

ARC๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ retain๊ณผ release ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•ด์ค˜. ๋•๋ถ„์— ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ๋œ ์‹ ๊ฒฝ ์“ฐ๋ฉด์„œ๋„ ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์ง€.


// ARC ํ™˜๊ฒฝ์—์„œ๋Š” ์ด๋ ‡๊ฒŒ๋งŒ ํ•ด๋„ ๋ผ
NSString *myString = [[NSString alloc] initWithString:@"Hello, ARC!"];
// ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ๋˜๋‹ˆ๊นŒ release ๋ถˆํ•„์š”

๐Ÿ’ก ์žฌ๋Šฅ๋„ท Tip! ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ iOS ๊ฐœ๋ฐœ์˜ ๊ทผ๋ณธ์„ ์•„๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„. ์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ๊นŠ์ด ์žˆ๋Š” ์ง€์‹์„ ๊ณต์œ ํ•˜๋ฉด, ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋„์›€์ด ๋  ๊ฑฐ์•ผ. ํŠนํžˆ ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ๋Š” ์ •๋ง ๊ท€์ค‘ํ•œ ์ •๋ณด๊ฐ€ ๋  ์ˆ˜ ์žˆ์ง€!

๐Ÿ”„ Weak References์™€ Strong References

ARC ํ™˜๊ฒฝ์—์„œ๋Š” 'weak'์™€ 'strong' ์ฐธ์กฐ๋ผ๋Š” ๊ฐœ๋…๋„ ์ค‘์š”ํ•ด์ ธ. ์ด๊ฑด ๋งˆ์น˜ ๊ด€๊ณ„์˜ ๊ฐ•๋„๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•ด.

  • Strong Reference: ๊ธฐ๋ณธ์ ์ธ ์ฐธ์กฐ ๋ฐฉ์‹. ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์„ ์—ฐ์žฅ์‹œ์ผœ.
  • Weak Reference: ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„. ์ฃผ๋กœ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ด.

@property (strong, nonatomic) NSString *strongString;
@property (weak, nonatomic) NSString *weakString;

Weak reference๋Š” ํŠนํžˆ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋ผ. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ .

๐Ÿ” ๋””๋ฒ„๊น…๊ณผ ๋„๊ตฌ๋“ค

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋กœ ๊ฐœ๋ฐœํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ๋•๋Š” ์—ฌ๋Ÿฌ ๋„๊ตฌ๋“ค์ด ์žˆ์–ด:

  • Instruments: Xcode์— ๋‚ด์žฅ๋œ ๊ฐ•๋ ฅํ•œ ํ”„๋กœํŒŒ์ผ๋ง ๋„๊ตฌ
  • Leaks: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์ฐพ์•„์ฃผ๋Š” ๋„๊ตฌ
  • Allocations: ๊ฐ์ฒด ํ• ๋‹น๊ณผ ํ•ด์ œ๋ฅผ ์ถ”์ ํ•˜๋Š” ๋„๊ตฌ

์ด๋Ÿฐ ๋„๊ตฌ๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์–ด.

๐ŸŒฑ ์„ฑ์žฅ Tip! ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋„๊ตฌ๋“ค์„ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๊ฒƒ๋„ ํ•˜๋‚˜์˜ ํฐ ์žฌ๋Šฅ์ด์•ผ. ์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ๋„๊ตฌ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•œ ํŠœํ† ๋ฆฌ์–ผ์„ ์ œ๊ณตํ•˜๋ฉด ์–ด๋–จ๊นŒ? ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ด€์‹ฌ์„ ๊ฐ€์งˆ ๊ฑฐ์•ผ!

๐Ÿš€ Chapter 4: ์Šค์œ„ํ”„ํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ - ํ˜„๋Œ€ํ™”์˜ ๊ฒฐ์ •์ฒด ๐Ÿ’Ž

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ 'ํž™ํ•œ ์‚ฌ์ดŒ' ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š”์ง€ ๊นŠ์ด ๋“ค์—ฌ๋‹ค๋ณผ ์‹œ๊ฐ„์ด์•ผ. ์Šค์œ„ํ”„ํŠธ๋Š” ํ˜„๋Œ€์ ์ด๊ณ  ์•ˆ์ „ํ•œ ์–ธ์–ด๋ฅผ ๋ชฉํ‘œ๋กœ ๋งŒ๋“ค์–ด์กŒ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋„ ๋”์šฑ ์Šค๋งˆํŠธํ•ด์กŒ์–ด.

๐ŸŒŸ ARC์˜ ์ง„ํ™”: ์™„์ „ ์ž๋™ํ™”๋œ ์ฒญ์†Œ ๋กœ๋ด‡

์Šค์œ„ํ”„ํŠธ์—์„œ์˜ ARC๋Š” ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๊ทธ๊ฒƒ๋ณด๋‹ค ํ•œ์ธต ๋” ๋ฐœ์ „ํ–ˆ์–ด. ๋งˆ์น˜ ์ธ๊ณต์ง€๋Šฅ์ด ํƒ‘์žฌ๋œ ์ตœ์‹ ํ˜• ๋กœ๋ด‡ ์ฒญ์†Œ๊ธฐ ๊ฐ™์ง€.

์Šค์œ„ํ”„ํŠธ์˜ ARC๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ๋Œ€๋ถ€๋ถ„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ฒฐ์ •์„ ๋‚ด๋ ค. ์ด๋Š” ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ณ  ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋ผ.


class Person {
    var name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

var reference1: Person?
var reference2: Person?
var reference3: Person?

reference1 = Person(name: "John Appleseed")
// Prints "John Appleseed is being initialized"

reference2 = reference1
reference3 = reference1

reference1 = nil
reference2 = nil

reference3 = nil
// Prints "John Appleseed is being deinitialized"

์ด ์˜ˆ์ œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋˜๋Š” ์ˆœ๊ฐ„ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋ผ. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋ฅผ ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†์–ด์ง„ ๊ฑฐ์ง€.

๐Ÿ”— ๊ฐ•ํ•œ ์ฐธ์กฐ vs ์•ฝํ•œ ์ฐธ์กฐ vs ๋ฏธ์†Œ์œ  ์ฐธ์กฐ

์Šค์œ„ํ”„ํŠธ๋Š” ์ฐธ์กฐ ํƒ€์ž…์˜ ๊ด€๊ณ„๋ฅผ ๋”์šฑ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์–ด:

  • ๊ฐ•ํ•œ ์ฐธ์กฐ(Strong Reference): ๊ธฐ๋ณธ ์ฐธ์กฐ ํƒ€์ž…. ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์„ ์—ฐ์žฅ์‹œ์ผœ.
  • ์•ฝํ•œ ์ฐธ์กฐ(Weak Reference): ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„. nil์ด ๋  ์ˆ˜ ์žˆ์–ด.
  • ๋ฏธ์†Œ์œ  ์ฐธ์กฐ(Unowned Reference): ์•ฝํ•œ ์ฐธ์กฐ์™€ ๋น„์Šทํ•˜์ง€๋งŒ, nil์ด ๋  ์ˆ˜ ์—†์–ด. ํ•ญ์ƒ ๊ฐ’์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด.

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    weak var tenant: Person?
    deinit { print("Apartment \(unit) is being deinitialized") }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

์ด ์˜ˆ์ œ์—์„œ `Apartment`์˜ `tenant` ์†์„ฑ์ด weak๋กœ ์„ ์–ธ๋œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์–ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ง€.

๊ฐ•ํ•œ ์ฐธ์กฐ์™€ ์•ฝํ•œ ์ฐธ์กฐ ๋‹ค์ด์–ด๊ทธ๋žจ Person Apartment ๊ฐ•ํ•œ ์ฐธ์กฐ ์•ฝํ•œ ์ฐธ์กฐ

์ด ๋‹ค์ด์–ด๊ทธ๋žจ์€ Person๊ณผ Apartment ์‚ฌ์ด์˜ ๊ด€๊ณ„๋ฅผ ๋ณด์—ฌ์ค˜. Person์€ Apartment์— ๋Œ€ํ•ด ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , Apartment๋Š” Person์— ๋Œ€ํ•ด ์•ฝํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์ง€.

๐Ÿ”„ ํด๋กœ์ €์™€ ์บก์ฒ˜ ๋ฆฌ์ŠคํŠธ

์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” ํด๋กœ์ €๊ฐ€ ๊ฐ์ฒด๋ฅผ ์บก์ฒ˜ํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•ํ•œ ์ฐธ์กฐ ์ˆœํ™˜๋„ ์šฐ์•„ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด.

์บก์ฒ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋กœ์ € ๋‚ด์—์„œ ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ์ฐธ์กฐํ• ์ง€ ๋ช…์‹œ์ ์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ์ง€. ์ด๋ ‡๊ฒŒ ๋ง์ด์•ผ:


class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = { [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

์—ฌ๊ธฐ์„œ `[unowned self]`๋Š” ํด๋กœ์ €๊ฐ€ self๋ฅผ ๋ฏธ์†Œ์œ  ์ฐธ์กฐ๋กœ ์บก์ฒ˜ํ•œ๋‹ค๋Š” ๊ฑธ ๋‚˜ํƒ€๋‚ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ•ํ•œ ์ฐธ์กฐ ์ˆœํ™˜์„ ํ”ผํ•  ์ˆ˜ ์žˆ์–ด.

๐Ÿง  ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ

์Šค์œ„ํ”„ํŠธ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ์— ํฐ ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์–ด. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ์˜ค๋ฅ˜๋ฅผ ๋ฏธ๋ฆฌ ์žก์•„๋‚ด์ฃผ์ง€.

์˜ˆ๋ฅผ ๋“ค์–ด, ์Šค์œ„ํ”„ํŠธ๋Š” ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ๋Œ€ํ•œ ๋™์‹œ ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•ด. ์ด๊ฑด ์ •๋ง ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ด์•ผ. ์™œ๋ƒํ•˜๋ฉด ๋™์‹œ ์ ‘๊ทผ์œผ๋กœ ์ธํ•œ ๋ฒ„๊ทธ๋Š” ์ฐพ๊ธฐ๊ฐ€ ์ •๋ง ์–ด๋ ต๊ฑฐ๋“ .


var stepSize = 1

func increment(_ number: inout Int) {
    number += stepSize
}

// ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด
// increment(&stepSize)

// ๋Œ€์‹  ์ด๋ ‡๊ฒŒ ํ•ด์•ผ ํ•ด
var copyOfStepSize = stepSize
increment(&copyOfStepSize)
stepSize = copyOfStepSize

์ด ์˜ˆ์ œ์—์„œ `stepSize`๋ฅผ ์ง์ ‘ `increment` ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ. ์™œ๋ƒํ•˜๋ฉด `stepSize`๊ฐ€ ํ•จ์ˆ˜ ๋‚ด๋ถ€์™€ ์™ธ๋ถ€์—์„œ ๋™์‹œ์— ์ ‘๊ทผ๋˜๊ธฐ ๋•Œ๋ฌธ์ด์•ผ. ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€.

๐ŸŽ“ ํ•™์Šต Tip! ์Šค์œ„ํ”„ํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ ๊ธฐ๋Šฅ์€ ์ •๋ง ๊ฐ•๋ ฅํ•ด. ํ•˜์ง€๋งŒ ์ด๋ฅผ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ณ  ํ™œ์šฉํ•˜๋ ค๋ฉด ์—ฐ์Šต์ด ํ•„์š”ํ•ด. ์žฌ๋Šฅ๋„ท์—์„œ ์ด๋Ÿฐ ๊ณ ๊ธ‰ ์ฃผ์ œ์— ๋Œ€ํ•œ ์‹ค์Šต ๊ณผ์ œ๋ฅผ ์ œ๊ณตํ•˜๋ฉด ์–ด๋–จ๊นŒ? ๊ฐœ๋ฐœ์ž๋“ค์˜ ์‹ค๋ ฅ ํ–ฅ์ƒ์— ํฐ ๋„์›€์ด ๋  ๊ฑฐ์•ผ!

๐Ÿ” ์Šค์œ„ํ”„ํŠธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋””๋ฒ„๊น…

์Šค์œ„ํ”„ํŠธ๋„ ๊ฐ•๋ ฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋””๋ฒ„๊น… ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•ด:

  • ๋ฉ”๋ชจ๋ฆฌ ๊ทธ๋ž˜ํ”„ ๋””๋ฒ„๊ฑฐ: ๊ฐ์ฒด ๊ฐ„์˜ ์ฐธ์กฐ ๊ด€๊ณ„๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ค˜
  • ์ฃผ์†Œ ์‚ด๊ท ๊ธฐ(Address Sanitizer): ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํƒ์ง€ํ•ด
  • ์Šค๋ ˆ๋“œ ์‚ด๊ท ๊ธฐ(Thread Sanitizer): ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ์ฐพ์•„๋‚ด

์ด๋Ÿฐ ๋„๊ตฌ๋“ค์„ ํ™œ์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ์ฐพ๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด. ํŠนํžˆ ๋ฉ”๋ชจ๋ฆฌ ๊ทธ๋ž˜ํ”„ ๋””๋ฒ„๊ฑฐ๋Š” ๋ณต์žกํ•œ ์ฐธ์กฐ ๊ด€๊ณ„๋ฅผ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋‹ˆ๊นŒ ์ •๋ง ์œ ์šฉํ•ด.

๐Ÿ† Chapter 5: ์Šค์œ„ํ”„ํŠธ vs ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C - ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ์ตœ์ข… ๋Œ€๊ฒฐ! ๐ŸฅŠ

์ž, ์ด์ œ ์šฐ๋ฆฌ์˜ ๋‘ ์ฃผ์ธ๊ณต์„ ๋‚˜๋ž€ํžˆ ๋†“๊ณ  ๋น„๊ตํ•ด๋ณผ ์‹œ๊ฐ„์ด์•ผ. ์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C, ์–ด๋–ค ์ ์ด ๋‹ค๋ฅด๊ณ  ์–ด๋–ค ์ ์ด ๋น„์Šทํ• ๊นŒ?

๐Ÿ”„ ๊ณตํ†ต์ : ARC์˜ ๊ธฐ๋ณธ ์›๋ฆฌ

์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C ๋ชจ๋‘ ARC๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•ด. ์ด๊ฑด ์ •๋ง ํฐ ๊ณตํ†ต์ ์ด์•ผ.

  • ๋‘˜ ๋‹ค ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์„ ๊ด€๋ฆฌํ•ด
  • ๊ฐ•ํ•œ ์ฐธ์กฐ์™€ ์•ฝํ•œ ์ฐธ์กฐ์˜ ๊ฐœ๋…์ด ์กด์žฌํ•ด
  • ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ด

๐Ÿ”ฅ ์ฐจ์ด์ : ๋” ์Šค๋งˆํŠธํ•ด์ง„ ์Šค์œ„ํ”„ํŠธ

ํ•˜์ง€๋งŒ ์Šค์œ„ํ”„ํŠธ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ ์—์„œ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋ฅผ ์•ž์„œ๊ฐ€๊ณ  ์žˆ์–ด:

ํŠน์ง• ์Šค์œ„ํ”„ํŠธ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C
์ปดํŒŒ์ผ ์‹œ์  ์ตœ์ ํ™” ๊ฐ•๋ ฅํ•จ ์ œํ•œ์ 
๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ ๋งค์šฐ ๋†’์Œ ์ค‘๊ฐ„
๊ฐ’ ํƒ€์ž… ์ง€์› ๊ด‘๋ฒ”์œ„ํ•จ ์ œํ•œ์ 
ํด๋กœ์ € ์บก์ฒ˜ ๋ฆฌ์ŠคํŠธ ์ง€์› ๋ฏธ์ง€์›

์Šค์œ„ํ”„ํŠธ์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์ปดํŒŒ์ผ ์‹œ์ ์—์„œ์˜ ๊ฐ•๋ ฅํ•œ ์ตœ์ ํ™”์•ผ. ์ด๋Š” ๋Ÿฐํƒ€์ž„ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ค๊ณ , ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ๋ฏธ๋ฆฌ ์žก์•„๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜.

๐Ÿ‹๏ธโ€โ™‚๏ธ ์„ฑ๋Šฅ ๋น„๊ต

์ผ๋ฐ˜์ ์œผ๋กœ ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์ธก๋ฉด์—์„œ ๋” ํšจ์œจ์ ์ด๋ผ๊ณ  ์•Œ๋ ค์ ธ ์žˆ์–ด. ํ•˜์ง€๋งŒ ์ด๊ฑด ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์–ด.

์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C ์„ฑ๋Šฅ ๋น„๊ต ์Šค์œ„ํ”„ํŠธ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ

์ด ๊ทธ๋ž˜ํ”„๋Š” ์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ์„ ๋ณด์—ฌ์ค˜. ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์กฐ๊ธˆ ๋” ํšจ์œจ์ ์ด์ง€๋งŒ, ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋„ ์—ฌ์ „ํžˆ ๊ฐ•๋ ฅํ•ด.

๐Ÿค” ์–ด๋–ค ์–ธ์–ด๋ฅผ ์„ ํƒํ•ด์•ผ ํ• ๊นŒ?

๊ฒฐ๊ตญ ์„ ํƒ์€ ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ๊ฐœ๋ฐœ์ž์˜ ๊ฒฝํ—˜์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ๊ฑฐ์•ผ.

  • ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ์Šค์œ„ํ”„ํŠธ๊ฐ€ ์ข‹์€ ์„ ํƒ์ด ๋  ๊ฑฐ์•ผ
  • ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋ฅผ ์œ ์ง€๋ณด์ˆ˜ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C ์ง€์‹์ด ํ•„์š”ํ•  ๊ฑฐ๊ณ 
  • ๋‘ ์–ธ์–ด๋ฅผ ๋ชจ๋‘ ์•Œ๋ฉด ๊ฐ€์žฅ ์ด์ƒ์ ์ด๊ฒ ์ง€!

๐Ÿ’ก ์žฌ๋Šฅ๋„ท Tip! ๋‘ ์–ธ์–ด์˜ ์žฅ๋‹จ์ ์„ ๊นŠ์ด ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ๊ฐ€์น˜ ์žˆ๋Š” ๊ธฐ์ˆ ์ด์•ผ. ์žฌ๋Šฅ๋„ท์—์„œ ์ด ๋‘ ์–ธ์–ด๋ฅผ ๋น„๊ต ๋ถ„์„ํ•˜๋Š” ๊ฐ•์ขŒ๋ฅผ ๊ฐœ์„คํ•˜๋ฉด ์–ด๋–จ๊นŒ? ๋งŽ์€ iOS ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ด€์‹ฌ์„ ๊ฐ€์งˆ ๊ฑฐ์•ผ!

๐ŸŽญ Chapter 6: ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค - ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ํ˜„์žฅ ๐Ÿ—๏ธ

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ์‹ค์ œ ์ƒํ™ฉ์— ์ ์šฉํ•ด๋ณผ ์‹œ๊ฐ„์ด์•ผ. ๊ฐœ๋ฐœ์ž๋“ค์ด ์ž์ฃผ ๋งˆ์ฃผ์น˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‚ดํŽด๋ณด๊ณ , ์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—์„œ ๊ฐ๊ฐ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์ž.

๐Ÿ”„ ์‹œ๋‚˜๋ฆฌ์˜ค 1: ์ˆœํ™˜ ์ฐธ์กฐ ํ•ด๊ฒฐํ•˜๊ธฐ

๊ฐ€์žฅ ํ”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ”๋กœ ์ˆœํ™˜ ์ฐธ์กฐ์•ผ. ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

์Šค์œ„ํ”„ํŠธ์—์„œ์˜ ํ•ด๊ฒฐ์ฑ…:


class Person {
    let name: String
    weak var apartment: Apartment?
    
    init(name: String) {
        self.name = name
    }
    
    deinit {
        print("\(name) is being deinitialized")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person?
    
    init(unit: String) {
        self.unit = unit
    }
    
    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(unit: "4A")

john?.apartment = unit4A
unit4A?.tenant = john

john = nil
unit4A = nil
// ๋‘ ๊ฐ์ฒด ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ํ•ด์ œ๋จ

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—์„œ์˜ ํ•ด๊ฒฐ์ฑ…:


@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, weak) Apartment *apartment;
@end

@interface Apartment : NSObject
@property (nonatomic, strong) NSString *unit;
@property (nonatomic, weak) Person *tenant;
@end

@implementation Person
- (void)dealloc {
    NSLog(@"%@ is being deinitialized", self.name);
}
@end

@implementation Apartment
- (void)dealloc {
    NSLog(@"Apartment %@ is being deinitialized", self.unit);
}
@end

Person *john = [[Person alloc] init];
john.name = @"John";
Apartment *unit4A = [[Apartment alloc] init];
unit4A.unit = @"4A";

john.apartment = unit4A;
unit4A.tenant = john;

john = nil;
unit4A = nil;
// ๋‘ ๊ฐ์ฒด ๋ชจ๋‘ ์ •์ƒ์ ์œผ๋กœ ํ•ด์ œ๋จ

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ weak ์ฐธ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์–ด. ์Šค์œ„ํ”„ํŠธ์˜ ๊ฒฝ์šฐ ์ข€ ๋” ๊ฐ„๊ฒฐํ•œ ๋ฌธ๋ฒ•์œผ๋กœ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์ง€.

๐Ÿ”„ ์‹œ๋‚˜๋ฆฌ์˜ค 2: ํด๋กœ์ €์™€ ์บก์ฒ˜ ๋ฆฌ์ŠคํŠธ

ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ self๋ฅผ ์บก์ฒ˜ํ•˜๋ฉด ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด. ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ๊นŒ?

์Šค์œ„ํ”„ํŠธ์—์„œ์˜ ํ•ด๊ฒฐ์ฑ…:


class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = { [weak self] in
        guard let self = self else { return "" }
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
paragraph = nil
// "p is being deinitialized" ์ถœ๋ ฅ๋จ

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—์„œ์˜ ํ•ด๊ฒฐ์ฑ…:


@interface HTMLElement : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *text;
@property (nonatomic, copy) NSString *(^asHTML)(void);
- (instancetype)initWithName:(NSString *)name text:(NSString *)text;
@end

@implementation HTMLElement

- (instancetype)initWithName:(NSString *)name text:(NSString *)text {
    if (self = [super init]) {
        _name = name;
        _text = text;
        __weak typeof(self) weakSelf = self;
        _asHTML = ^NSString *{
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if (strongSelf) {
                if (strongSelf.text) {
                    return [NSString stringWithFormat:@"<%@>%@</%@>", strongSelf.name, strongSelf.text, strongSelf.name];
                } else {
                    return [NSString stringWithFormat:@"<%@ />", strongSelf.name];
                }
            }
            return @"";
        };
    }
    return self;
}

- (void)dealloc {
    NSLog(@"%@ is being deinitialized", self.name);
}

@end

HTMLElement *paragraph = [[HTMLElement alloc] initWithName:@"p" text:@"hello, world"];
NSLog(@"%@", paragraph.asHTML());
paragraph = nil;
// "p is being deinitialized" ์ถœ๋ ฅ๋จ

์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” ์บก์ฒ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ„๋‹จํžˆ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—์„œ๋Š” ์•ฝํ•œ ์ฐธ์กฐ์™€ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ์กฐํ•ฉํ•ด ์‚ฌ์šฉํ•ด์•ผ ํ•ด. ์Šค์œ„ํ”„ํŠธ์˜ ๋ฐฉ์‹์ด ์ข€ ๋” ์ง๊ด€์ ์ด๊ณ  ์•ˆ์ „ํ•ด ๋ณด์ด์ง€?

๐ŸŒฑ ์„ฑ์žฅ Tip! ์ด๋Ÿฐ ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋งŽ์ด ์ ‘ํ•ด๋ณด๋Š” ๊ฒŒ ์ค‘์š”ํ•ด. ์žฌ๋Šฅ๋„ท์—์„œ ๋‹ค์–‘ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค๋ฃจ๋Š” ์›Œํฌ์ƒต์„ ๊ฐœ์ตœํ•˜๋ฉด ์–ด๋–จ๊นŒ? ๊ฐœ๋ฐœ์ž๋“ค์ด ์‹ค์ œ ์ƒํ™ฉ์—์„œ ์–ด๋–ป๊ฒŒ ๋Œ€์ฒ˜ํ•ด์•ผ ํ• ์ง€ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ!

๐Ÿ”„ ์‹œ๋‚˜๋ฆฌ์˜ค 3: ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํŒจํ„ด์€ iOS ๊ฐœ๋ฐœ์—์„œ ์ •๋ง ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ๋„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ•ด.

์Šค์œ„ํ”„ํŠธ์—์„œ์˜ ํ•ด๊ฒฐ์ฑ…:


protocol DataManagerDelegate: AnyObject {
    func dataManagerDidUpdate(_ data: [String])
}

class DataManager {
    weak var delegate: DataManagerDelegate?
    
    func fetchData() {
        // ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง
        let newData = ["Apple", "Banana", "Cherry"]
        delegate?.dataManagerDidUpdate(newData)
    }
}

class ViewController: UIViewController, DataManagerDelegate {
    let dataManager = DataManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dataManager.delegate = self
    }
    
    func dataManagerDidUpdate(_ data: [String]) {
        print("Data updated: \(data)")
    }
}

์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์—์„œ์˜ ํ•ด๊ฒฐ์ฑ…:


@protocol DataManagerDelegate;

@interface DataManager : NSObject
@property (nonatomic, weak) id<DataManagerDelegate> delegate;
- (void)fetchData;
@end

@protocol DataManagerDelegate <NSObject>
- (void)dataManagerDidUpdate:(NSArray<NSString *> *)data;
@end

@implementation DataManager
- (void)fetchData {
    // ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง
    NSArray *newData = @[@"Apple", @"Banana", @"Cherry"];
    [self.delegate dataManagerDidUpdate:newData];
}
@end

@interface ViewController : UIViewController <DataManagerDelegate>
@property (nonatomic, strong) DataManager *dataManager;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.dataManager = [[DataManager alloc] init];
    self.dataManager.delegate = self;
}

- (void)dataManagerDidUpdate:(NSArray<NSString *> *)data {
    NSLog(@"Data updated: %@", data);
}

@end

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ weak ์ฐธ์กฐ๋กœ ์„ ์–ธํ•ด ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์–ด. ์Šค์œ„ํ”„ํŠธ์—์„œ๋Š” ํ”„๋กœํ† ์ฝœ์— AnyObject๋ฅผ ์ถ”๊ฐ€ํ•ด ํด๋ž˜์Šค๋งŒ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ œํ•œํ•˜๊ณ  ์žˆ์ง€.

๐ŸŽฌ Chapter 7: ๊ฒฐ๋ก  - ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ๋ฏธ๋ž˜ ๐Ÿ”ฎ

์ž, ์šฐ๋ฆฌ์˜ ๊ธด ์—ฌ์ •์ด ๊ฑฐ์˜ ๋๋‚˜๊ฐ€๊ณ  ์žˆ์–ด. ์Šค์œ„ํ”„ํŠธ์™€ ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์ •๋ง ๋งŽ์€ ๊ฒƒ์„ ๋ฐฐ์› ์ง€? ์ด์ œ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ „์ฒด๋ฅผ ์ •๋ฆฌํ•˜๊ณ , ์•ž์œผ๋กœ์˜ ์ „๋ง์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด๋ณผ๊ฒŒ.

๐Ÿ” ํ•ต์‹ฌ ์š”์•ฝ

  1. ARC์˜ ์ค‘์š”์„ฑ: ๋‘ ์–ธ์–ด ๋ชจ๋‘ ARC๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•ด. ์ด๋Š” ๊ฐœ๋ฐœ์ž์˜ ๋ถ€๋‹ด์„ ํฌ๊ฒŒ ์ค„์—ฌ์ฃผ์ง€.
  2. ์Šค์œ„ํ”„ํŠธ์˜ ์ง„๋ณด: ์Šค์œ„ํ”„ํŠธ๋Š” ๋” ์•ˆ์ „ํ•˜๊ณ  ํšจ์œจ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด. ํŠนํžˆ ์ปดํŒŒ์ผ ์‹œ์ ์˜ ์ตœ์ ํ™”๊ฐ€ ๋›ฐ์–ด๋‚˜.
  3. ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C์˜ ์œ ์‚ฐ: ์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C๋Š” ์—ฌ์ „ํžˆ ๋งŽ์€ ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์–ด. ๊ทธ๋ž˜์„œ ์•„์ง๋„ ์ค‘์š”ํ•œ ์œ„์น˜๋ฅผ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ์ง€.
  4. ์ˆœํ™˜ ์ฐธ์กฐ ์ฃผ์˜: ๋‘ ์–ธ์–ด ๋ชจ๋‘ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ๋ฅผ ์กฐ์‹ฌํ•ด์•ผ ํ•ด. weak๋‚˜ unowned ์ฐธ์กฐ๋ฅผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด.
  5. ํด๋กœ์ €์™€ ๋ธ”๋ก: ํด๋กœ์ €(์Šค์œ„ํ”„ํŠธ)๋‚˜ ๋ธ”๋ก(์˜ค๋ธŒ์ ํ‹ฐ๋ธŒ-C)์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ํŠนํžˆ ์ฃผ์˜ํ•ด์•ผ ํ•ด.

๐Ÿ”ฎ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ๋ฏธ๋ž˜

์•ž์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ๋ณ€ํ• ๊นŒ? ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์ธก์„ ํ•ด๋ณผ๊ฒŒ:

  • ๋” ์Šค๋งˆํŠธํ•œ ์ปดํŒŒ์ผ๋Ÿฌ: ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ จ ์ตœ์ ํ™”๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•  ๊ฑฐ์•ผ.
  • ์‹ค์‹œ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ๋ถ„์„: ์•ฑ ์‹คํ–‰ ์ค‘ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ๋ถ„์„ํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ๋ฐœ์ „ํ•  ๊ฑฐ์•ผ.
  • AI ๊ธฐ๋ฐ˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ: ์ธ๊ณต์ง€๋Šฅ์ด ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด ์ตœ์ ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์ „๋žต์„ ์ œ์•ˆํ•  ์ˆ˜๋„ ์žˆ์–ด.
  • ํ•˜๋“œ์›จ์–ด ์ง€์›: ์• ํ”Œ์˜ ์นฉ์ด ๋” ๋ฐœ์ „ํ•˜๋ฉด์„œ, ํ•˜๋“œ์›จ์–ด ๋ ˆ๋ฒจ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ง€์›ํ•  ์ˆ˜๋„ ์žˆ์–ด.

๐ŸŽ“ ํ•™์Šต Tip! ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ํ•ญ์ƒ ๋ณ€ํ™”ํ•˜๊ณ  ๋ฐœ์ „ํ•ด. ์ตœ์‹  ํŠธ๋ Œ๋“œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋Š” ๊ฒŒ ์ค‘์š”ํ•ด. ์žฌ๋Šฅ๋„ท์—์„œ ์ •๊ธฐ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ ์„ธ๋ฏธ๋‚˜๋ฅผ ์—ด๋ฉด ์–ด๋–จ๊นŒ? ๊ฐœ๋ฐœ์ž๋“ค์ด ํ•ญ์ƒ ์ตœ์‹  ๊ธฐ์ˆ ์„ ์ตํž ์ˆ˜ ์žˆ์„ ๊ฑฐ์•ผ!

๐ŸŒŸ ๋งˆ์ง€๋ง‰ ์กฐ์–ธ

๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” iOS ๊ฐœ๋ฐœ์—์„œ ์ •๋ง ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด์•ผ. ํ•˜์ง€๋งŒ ๋„ˆ๋ฌด ๊ฒ๋จน์„ ํ•„์š”๋Š” ์—†์–ด. ์ด๋ ‡๊ฒŒ ๊ธฐ์–ตํ•ด:

  1. ์‹ค์Šต์ด ์ค‘์š”ํ•ด: ์ด๋ก ๋งŒ ์•Œ๋ฉด ๋ถ€์กฑํ•ด. ์‹ค์ œ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋””๋ฒ„๊น…ํ•ด๋ณด๋Š” ๊ฒŒ ๊ฐ€์žฅ ์ข‹์€ ํ•™์Šต ๋ฐฉ๋ฒ•์ด์•ผ.
  2. ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•ด: Xcode์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ทธ๋ž˜ํ”„ ๋””๋ฒ„๊ฑฐ, Instruments ๊ฐ™์€ ๋„๊ตฌ๋“ค์„ ์ ๊ทน ํ™œ์šฉํ•ด๋ด.
  3. ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ํ•ด: ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ๋ฆฌ๋ทฐ๋ฐ›์•„. ์ƒˆ๋กœ์šด ์‹œ๊ฐ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์–ด.
  4. ๋Š์ž„์—†์ด ํ•™์Šตํ•ด: ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ์ˆ ์€ ๊ณ„์† ๋ฐœ์ „ํ•ด. ํ•ญ์ƒ ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ฐฐ์šฐ๋ ค๋Š” ์ž์„ธ๊ฐ€ ์ค‘์š”ํ•ด.

๊ธฐ์–ตํ•ด, ์™„๋ฒฝํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ์—†์–ด. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ณ„์†ํ•ด์„œ ๊ฐœ์„ ํ•˜๊ณ  ๋ฐœ์ „ํ•  ์ˆ˜ ์žˆ์–ด. ์ด ์—ฌ์ •์„ ์ฆ๊ธฐ๋ฉด์„œ, ๋” ๋‚˜์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๊ฐ€๋Š” ๊ณผ์ •์„ ์ฆ๊ฒจ๋ด!

์ž, ์ด์ œ ์ •๋ง ๋์ด์•ผ. ๊ธด ์—ฌ์ •์ด์—ˆ์ง€๋งŒ, ์ •๋ง ๊ฐ’์ง„ ์‹œ๊ฐ„์ด์—ˆ์–ด. ์ด์ œ ๋„ˆํฌ๋“ค์€ iOS ๊ฐœ๋ฐœ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ๋‹ฌ์ธ์ด ๋œ ๊ฑฐ์•ผ! ์•ž์œผ๋กœ์˜ ๊ฐœ๋ฐœ ์ธ์ƒ์— ์ด ์ง€์‹์ด ํฐ ๋„์›€์ด ๋˜๊ธธ ๋ฐ”๋ž„๊ฒŒ. ํ™”์ดํŒ…! ๐Ÿš€

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.