Study/ํ˜ผ๊ณต

[swift] ARC์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ

yeggrrr๐Ÿผ 2024. 4. 30. 20:31


<TIL>

์˜ค๋Š˜์€ iOS ์•ฑ ๊ฐœ๋ฐœ ์‹ฌํ™” ์ฃผ๊ฐ„ ์‹œ์ž‘ํ•˜๋Š” ๋‚ ์ด์—ˆ๋‹ค.
(ํŒ€๋„ ์ƒˆ๋กœ ๋ฐ”๋€Œ์—ˆ๋Š”๋ฐ, ๋‹ค๋“ค ๋„˜ ํ™œ๋‹ฌํ•˜์…”์„œ ์ข‹๋‹ค..โ˜บ๏ธ)

๊ฐ•์˜๋Š” ๋‹ค ๋“ค์—ˆ๋Š”๋ฐ,
์•„์ง ์ „์ฒด์ ์œผ๋กœ ์ดํ•ด๋ฅผ ๋ชป ํ•œ ๊ฒƒ ๊ฐ™์•„์„œ ๋‚ด์ผ ํ•œ ๋ฒˆ ๋” ๋“ฃ๊ณ  ์ •๋ฆฌํ•  ์˜ˆ์ •์ด๋‹ค.

์˜ค๋Š˜์€ ์ง€๋‚œ Escaping Closure ๊ฒŒ์‹œ๊ธ€์— ์ด์–ด์„œ
ARC์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.



 

ARC


ARC๋Š” Automatic Reference Counting์˜ ์•ฝ์ž๋กœ
Swift๋Š” ์ด ARC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Heap ์˜์—ญ์˜ ๊ฐ์ฒด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


Swift๋Š” ์ปดํŒŒ์ผ ์‹œ์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ ์ ˆํžˆ ๋„ฃ์–ด์คŒ์œผ๋กœ์จ
๊ฐœ๋ฐœ์ž๊ฐ€ ์ˆ˜๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.โ˜บ๏ธ


RC(Reference Counting)์€ ๋ง ๊ทธ๋Œ€๋กœ!!
์ฐธ์กฐ(reference)๋ฅผ ์„ธ์„œ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐ๋  ๋•Œ ์ฐธ์กฐ๊ฐ’์„ ๋Š˜๋ฆฌ๊ณ ,
๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์—๋Š” ์ฐธ์กฐ๊ฐ’์„ ์ค„์ด๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ
์ฐธ์กฐ๊ฐ’์ด 0์ด ๋  ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.


- ํž™(Heap)๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ
- ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋Š” ์ž์‹ ์˜ RC(Reference Count) ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ



์ด ์ฐธ์กฐ(reference) ๋ฐฉ๋ฒ•์œผ๋กœ 4๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


1. Strong Reference(๊ฐ•ํ•œ ์ฐธ์กฐ)
2. Circular Reference(์ˆœํ™˜ ์ฐธ์กฐ)
3. Weak Reference(์•ฝํ•œ ์ฐธ์กฐ)
4. Unowned Reference(๋ฏธ์†Œ์œ  ์ฐธ์กฐ)


์ด 4๊ฐ€์ง€๋ฅผ ์‚ดํŽด๋ณด๊ธฐ ์ „์—
๊ฐ„๋‹จํ•˜๊ฒŒ 'Swift ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ'์— ๋Œ€ํ•ด์„œ ๋จผ์ € ์•Œ์•„๋ด…์‹œ๋‹ค!



 

Swift ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ

 


ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋ฉด,
์šด์˜์ฒด์ œ(OS)๋Š” ๋ฉ”๋ชจ๋ฆฌ(RAM)์— ์ด ํ”„๋กœ๊ทธ๋žจ์„ ์œ„ํ•œ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ ๊ณต๊ฐ„์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ ์˜์—ญ(Code), ๋ฐ์ดํ„ฐ ์˜์—ญ(Data), ํž™ ์˜์—ญ(Heap), ์Šคํƒ ์˜์—ญ(Stack)์œผ๋กœ
4๊ฐ€์ง€ ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.



1. Code ์˜์—ญ

- ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ์ฝ”๋“œ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

- ์ปดํŒŒ์ผ๋œ ์†Œ์Šค ์ฝ”๋“œ์™€ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ช…๋ น์–ด๋“ค์ด ์ €์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


- ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ๊ธฐ๊ณ„์–ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. (ex.0010101)


- ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ฒฐ์ •๋˜๊ณ , ์ค‘๊ฐ„์— ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก Read-Only ํ˜•ํƒœ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.




2. Data ์˜์—ญ

- ์ „์—ญ ๋ณ€์ˆ˜(global vaiables)์™€ ์ •์  ๋ณ€์ˆ˜(static variables), ์ƒ์ˆ˜(constants)๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

- ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘ ์‹œ ํ• ๋‹น๋˜๊ณ  ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. (ex. static)
(= ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ ๋˜์–ด์•ผ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋จ)

- ์‹คํ–‰ ๋„์ค‘ ๋ณ€์ˆ˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋‹ˆ Read-Write์œผ๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค.
 

 

3. Heap ์˜์—ญ

- ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘(๋Ÿฐํƒ€์ž„) ๋™์ ์œผ๋กœ ํ• ๋‹น๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

- ๋Ÿฐํƒ€์ž„ ์ค‘์— ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ๋˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- ํž™์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ์ง์ ‘์ ์œผ๋กœ ํฌ์ธํ„ฐ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ(์ฐธ์กฐ)๋ฉ๋‹ˆ๋‹ค.

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

- ์ฐธ์กฐํƒ€์ž…(Reference Type)์ด ์ €์žฅ๋˜๋Š” ์˜์—ญ์ž…๋‹ˆ๋‹ค.

- ์‚ฌ์šฉํ•˜๊ณ  ๋‚œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋ฅผ ํ•ด์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.
(๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด memory leak์ด ๋ฐœ์ƒ)

- Code, Data, Stack ์ค‘ ์œ ์ผํ•˜๊ฒŒ ๋Ÿฐํƒ€์ž„ ์‹œ์— ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์—
๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ํ™•์‹คํ•˜์ง€ ์•Š์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

- ์ธ์Šคํ„ด์Šค๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„

์žฅ์  - ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ์— ์ œํ•œ์ด ์—†์Œ
- ๋ฒ”์œ„๊ฐ€ ์ „์—ญ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชจ๋“  ํ•จ์ˆ˜์—์„œ ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ์Œ
๋‹จ์  - ํ• ๋‹น ์ž‘์—…, ํ•ด์ œ ์ž‘์—…์œผ๋กœ ์ธํ•œ ์†๋„ ์ €ํ•˜
- ํž™ ์†์ƒ(์ด์ค‘ ํ•ด์ œ, ํ•ด์ œ ํ›„ ์‚ฌ์šฉ ๋“ฑ)์œผ๋กœ ์ธํ•œ ์†๋„ ์ €ํ•˜
- ํž™ ๊ฒฝํ•ฉ(2๊ฐœ ์ด์ƒ์˜ thread๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ ค ํ•  ๋•Œ lock์ด ๊ฑธ๋ฆผ)์œผ๋กœ ์ธํ•œ ์†๋„ ์ €ํ•˜
- ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์•ผ ํ•จ(์•ˆ๊ทธ๋Ÿฌ๋ฉด memory leak ๋ฐœ์ƒ)

 

 

4. Stack ์˜์—ญ

- ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ๊ธฐ๊ณ„์–ด๋กœ ๋ณ€ํ™˜๋˜๋Š” ์‹œ์ (์ปดํŒŒ์ผ ํƒ€์ž„)์— ํฌ๊ธฐ๊ฐ€ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

- ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

- ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๋กœ์ปฌ ๋ณ€์ˆ˜(local variables), ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜(parameter), ๋ฐ˜ํ™˜ ์ฃผ์†Œ(return address)
๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ํ•„์š”ํ•œ ๊ธฐํƒ€ ์ •๋ณด๊ฐ€ ์Šคํƒ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

- ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์„ ๋งˆ์น˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

- ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌดํ•œํžˆ ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

- ์Šคํƒ์€ ํ›„์ž…์„ ์ถœ(LIFO)์˜ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

- ๊ฐ’ํƒ€์ž…(Value Type)์ด ์ €์žฅ๋˜๋Š” ์˜์—ญ์ž…๋‹ˆ๋‹ค.

- ์ธ์Šคํ„ด์Šค๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„

์žฅ์  - CPU๊ฐ€ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๋งค์šฐ ๋น ๋ฆ„
- ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ํ•ด์ œ ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋จ
๋‹จ์  - ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ์— ๋Œ€ํ•œ ์ œํ•œ์ด ์žˆ์Œ
- ์ง€์—ญ ๋ณ€์ˆ˜๋งŒ ์•ก์„ธ์Šค๊ฐ€ ๊ฐ€๋Šฅํ•จ

 



๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๋ฅผ ๋ชจ๋ฅด๊ฑฐ๋‚˜, ์Šคํƒ์— ์ €์žฅํ•˜๊ธฐ์—๋Š” ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด?
ํž™(Heap)์— ํ• ๋‹นํ•˜๋ฉด ๋˜๊ณ ,
๊ทธ ์™ธ์—๋Š” ์Šคํƒ(Stack)์— ํ• ๋‹นํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


์Šคํƒ(Stack)์— ๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ๋˜๋ฉด,
์Šคํƒ ์˜ค๋ฒ„ ํ”Œ๋กœ์šฐ(Stack Overflow)๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.


Stack Overflow?๐Ÿง

 ํ•จ์ˆ˜๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, CPU๋Š” ๋ฐ˜ํ™˜ ์ฃผ์†Œ(return address)๋ฅผ ์Šคํƒ(Stack)์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํ˜ธ์ถœ์ด ์ข…๋ฃŒ๋˜๋ฉด, CPU๋Š” ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ํ˜ธ์ถœ์ž์—๊ฒŒ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๋์ด ์—†๋Š” ์žฌ๊ท€ ํ•จ์ˆ˜(recursive function)์„ ์‚ฌ์šฉํ•˜๋ฉด
CPU ์Šคํƒ์˜ ๊ณต๊ฐ„์ด ๋ถ€์กฑํ•ด์ง€๊ฒŒ ๋˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด
๋ฐ”๋กœ 'Stack Overflow' ์ž…๋‹ˆ๋‹ค.


 


 

๐Ÿ”ฅ๊ทธ๋Ÿผ ์ด์ œ!๐Ÿ”ฅ

์ด 4๊ฐ€์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ด…์‹œ๋‹ค!! :)






1. Strong Reference(๊ฐ•ํ•œ ์ฐธ์กฐ)

๊ธฐ๋ณธ์ ์œผ๋กœ Swift์—์„œ๋Š” ๋ณ€์ˆ˜๋‚˜ ์ƒ์ˆ˜๋Š” Strong Reference(๊ฐ•ํ•œ ์ฐธ์กฐ)๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.

class Person {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var person1: Person? = Person(name: "Yejin") // ๊ฐ•ํ•œ ์ฐธ์กฐ
var person2 = person1 // ๊ฐ•ํ•œ ์ฐธ์กฐ

person1 = nil



์œ„ ์˜ˆ์‹œ์ฒ˜๋Ÿผ person1 = nil ์„ ํ•˜๋”๋ผ๋„

๊ฐ•ํ•œ ์ฐธ์กฐ์˜ count๊ฐ€ ์ฆ๊ฐ€๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ฒด๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

 

 

2. Circular References(์ˆœํ™˜ ์ฐธ์กฐ)

์ˆœํ™˜ ์ฐธ์กฐ๋Š” ARC ์ž‘๋™ ๋ฐฉ์‹์˜ ํŠน์„ฑ์ƒ
๋‘ ๊ฐ€์ง€ ์ด์ƒ์˜ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ์— ๋Œ€ํ•œ Strong Reference(๊ฐ•ํ•œ ์ฐธ์กฐ) ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉด ์„œ๋กœ์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํ•ด์ œ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์œ ์ง€๋˜์–ด
Reference count๊ฐ€ ๊ฐ์†Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ด๋กœ ์ธํ•œ memory leak(๋ฉ”๋ชจ๋ฆฌ ๋ฆญ)์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

class Person {
    var name: String
    var pet: Pet? // Person์ด ์†Œ์œ ํ•˜๋Š” Pet

    init(name: String) {
        self.name = name
    }
}

class Pet {
    var species: String
    var owner: Person? // Pet์„ ์†Œ์œ ํ•˜๋Š” Person

    init(species: String) {
        self.species = species
    }
}

var person: Person? = Person(name: "Yejin") // Person ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ
var pet: Pet? = Pet(species: "Cheeze") // Pet ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ

person?.pet = pet // Person ํด๋ž˜์Šค์˜ pet์— Pet ์ธ์Šคํ„ด์Šค๋ฅผ ํ• ๋‹น
pet?.owner = person // Pet ํด๋ž˜์Šค์˜ owner์— Person ์ธ์Šคํ„ด์Šค๋ฅผ ํ• ๋‹น

 

๊ทธ๋ ‡๋‹ค๋ฉด,
๋‘ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๊ฐ€ ์„œ๋กœ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

๋‘ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๊ฐ€ ์„œ๋กœ์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์„œ
๊ฐ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณ„์† ์œ ์ง€ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ 'Strong Retain Cycle(๊ฐ•ํ•œ ์ˆœํ™˜ ์ฐธ์กฐ)'๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.


class Person {
    let name: String
    init(name: String) {
        self.name = name
    }
    
    var car: Car?
    
    deinit {
        print("deinit Person class instance")
    }
}

class Car {
    let model: String
    init(model: String) {
        self.model = model
    }
    
    var owner: Person?
    
    deinit {
        print("deinit Car class instance")
    }
}

Person ํด๋ž˜์Šค๋Š”
String ํƒ€์ž…์˜ name ํ”„๋กœํผํ‹ฐ์™€
nil๋กœ ์ดˆ๊ธฐํ™”๋œ ์˜ต์…”๋„ Car? ํƒ€์ž…์˜ car ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Car ํด๋ž˜์Šค์—๋Š”
String ํƒ€์ž…์˜ model ํ”„๋กœํผํ‹ฐ์™€
nil๋กœ ์ดˆ๊ธฐํ™”๋œ ์˜ต์…”๋„ Person? ํƒ€์ž…์˜ owner ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


์—ฌ๊ธฐ์— ๊ฐ ํƒ€์ž…์— ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ , ์ธ์Šคํ„ฐ์Šค๋ฅผ ํ• ๋‹นํ•ด๋ด…์‹œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  person์— car๋ฅผ

car์— owner๋ฅผ ํ• ๋‹นํ•ด๋ด…์‹œ๋‹ค.

var yejin: Person?
var benz: Car?

yejin = Person(name: "yejin")
benz = Car(model: "benz")

yejin!.car = benz
benz!.owner = yejin


์ด๋ ‡๊ฒŒ ํ•˜๋ฉด
์ด ๋‘ ์ธ์Šคํ„ด์Šค(yejin, benz)๋Š” ์„œ๋กœ ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

reference count๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด,

yejin์€
Person ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ•ํ•œ ์ฐธ์กฐ count + 1
Person ์ธ์Šคํ„ด์Šค๊ฐ€ Car ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ๊ฐ•ํ•œ ์ฐธ์กฐ count + 1
(yejin - reference count: 2)

benz๋Š”
Car ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ•ํ•œ ์ฐธ์กฐ count + 1
Car ์ธ์Šคํ„ด์Šค๊ฐ€ Person ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ๊ฐ•ํ•œ ์ฐธ์กฐ count + 1
(benz - reference count: 2)



์ด์ œ ๋‘ ๋ณ€์ˆ˜์— nil์„ ํ• ๋‹นํ•ด ๋ณผ๊นŒ์š”?

yejin = nil
benz = nil


yejin๊ณผ benz์— nil์„ ํ• ๋‹นํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ,
๊ฐ๊ฐ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ฌ๋ผ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ARC๋Š” ์ด๋Ÿฐ ๊ฐ•ํ•ญ ์ˆœํ™˜ ์ฐธ์กฐ์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋Š” ๊ด€๋ฆฌํ•ด์ฃผ์ง€ ์•Š์œผ๋‹ˆ ๋ฉ”๋ชจ๋ฆฌ ๋ฆญ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ

์•ฝํ•œ ์ฐธ์กฐ(weak reference), ๋ฏธ์†Œ์œ  ์ฐธ์กฐ(unowned reference)์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์ฐธ์กฐ ์œ ํ˜•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

3. Weak Reference(์•ฝํ•œ ์ฐธ์กฐ)

 

์•ฝํ•œ ์ฐธ์กฐ๋Š” ๊ฐ•ํ•œ ์ฐธ์กฐ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๊ฐ์ฒด์˜ ์ฐธ์กฐ count๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ๊ฐ์ฒด์˜ ์ƒ๋ช… ์ฃผ๊ธฐ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฉด์„œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณ€์ˆ˜ ํ˜น์€ ์†์„ฑ ์•ž์— weak ํ‚ค์›Œ๋“œ๋ฅผ ์จ์„œ Weak Reference์ž„์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์œ ์ง€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—
์ฐธ์กฐ๋˜๊ณ  ์žˆ๋Š” ๋™์•ˆ์—๋„ ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹น ํ•ด์ œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ARC๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹น ํ•ด์ œ๋  ๋•Œ,
ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์•ฝํ•œ ์ฐธ์กฐํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ nil๋กœ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์•ฝํ•œ ์ฐธ์กฐ๋Š” ํ•ญ์ƒ ์˜ต์…”๋„ ๋ณ€์ˆ˜์—๋งŒ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ƒ์ˆ˜์—๋Š” ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


class Car {
    let model: String
    init(model: String) {
        self.model = model
    }
    
    weak var owner: Person?
    
    deinit {
        print("deinit Car class instance")
    }
}


์•„๊นŒ์˜ ์ฝ”๋“œ์—์„œ Car ํด๋ž˜์Šค์˜ owner ํ”„๋กœํผํ‹ฐ์— weak๋ฅผ ๋ถ™์—ฌ
์•ฝํ•œ ์ฐธ์กฐ๋กœ ๋ฐ”๊ฟ”๋ณด์•˜์Šต๋‹ˆ๋‹ค.


์ด๋ ‡๊ฒŒ ํ•˜๋ฉด,

var yejin: Person?
var benz: Car?

yejin = Person(name: "yejin")
benz = Car(model: "benz")

yejin!.car = benz
benz!.owner = yejin


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

์ฆ‰, ์•„๊นŒ์ฒ˜๋Ÿผ (yejin = nil)
์ด๋ ‡๊ฒŒ yejin์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ nil๋กœ ๋งŒ๋“ค์–ด์„œ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๊นจ๊ฒŒ ๋˜๋ฉด,
Person ์ธ์Šคํ„ด์Šค๋Š” ๋”์ด์ƒ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Person ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ์•ฝํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๋˜
owner ํ”„๋กœํผํ‹ฐ๋Š” nil์ด ๋ฉ๋‹ˆ๋‹ค.


์•„๊นŒ๋Š” print๋˜์ง€ ์•Š๋˜๊ฒŒ ํ”„๋ฆฐํŠธ๊ฐ€ ๋์Šต๋‹ˆ๋‹ค.๐Ÿ˜ฒ

Car ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์ฐธ์กฐ ๋˜ํ•œ ๊นจ๊ฒŒ ๋˜๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๊ฒ ์ฃ ?


 

4. Unowned References(๋ฌด์†Œ์œ  ์ฐธ์กฐ)

๋ฌด์†Œ์œ  ์ฐธ์กฐ๋Š” ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค์™€ ์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๊ฐ™๊ฑฐ๋‚˜ ๋” ๊ธด ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฏธ์†Œ์œ  ์ฐธ์กฐ๋Š” ์•ฝํ•œ ์ฐธ์กฐ์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, optional ๊ฐ’์ด ์•„๋‹ˆ๋ผ์„œ nil๋กœ ์„ค์ •๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์ด๋ฏธ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋œ ์ƒํƒœ๋กœ ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด!
๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ(runtime error)๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์‚ฌ์šฉ ์‹œ์ ์— ๊ฐ์ฒด๊ฐ€ ์ด๋ฏธ ํ•ด์ œ๋˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํ™•์‹คํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
(ํ•ญ์ƒ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •)

๋ณ€์ˆ˜ ํ˜น์€ ์†์„ฑ ์•ž์— unowned ํ‚ค์›Œ๋“œ๋ฅผ ๋‘ฌ์„œ ๋ฌด์†Œ์œ  ์ฐธ์กฐ์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    
    deinit { print("deinit Customer Class instance") }
}

class CreditCard {
    let number: Int
    unowned let customer: Customer
    init(number: Int, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    
    deinit { print("deinit CreditCard Class instance") }
}

var fubao: Customer?
fubao = Customer(name: "fubao")
fubao!.card = CreditCard(number: 1234, customer: fubao!)


์œ„ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด,

fubao๋Š” Customer ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ ,

CreditCard ์ธ์Šคํ„ด์Šค์— customer์— ๋Œ€ํ•ด ๋ฌด์†Œ์œ  ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง„ Customer ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ fubao = nil์„ ํ•˜๊ฒŒ ๋˜๋ฉด,

deinitialize ๋๋‹ค๊ณ  ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

์ฆ‰, Customer์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์ฐธ์กฐ๊ฐ€ ํ•ด์ œ๋˜๋ฉด์„œ
Customer ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์ฐธ์กฐ๊ฐ€ ๋”์ด์ƒ ์—†์œผ๋ฏ€๋กœ ํ• ๋‹น ํ•ด์ œ๋˜์—ˆ๊ณ ,

CreditCard ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์ฐธ์กฐ ๋˜ํ•œ ์—†์–ด์ง€๋ฏ€๋กœ
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ• ๋‹น ํ•ด์ œ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.




ARC์— ๊ด€๋ จํ•ด์„œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€

์•„๋ž˜ Swift Documentation์œผ๋กœ Go!!


 

Documentation

 

docs.swift.org

 

์ˆ˜์ •์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ์žˆ๊ฑฐ๋‚˜ ํ‹€๋ฆฐ ๋‚ด์šฉ์ด ์žˆ๋‹ค๋ฉด, ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!!๐Ÿ™‹๐Ÿป‍โ™€๏ธ
์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.๐Ÿ˜†


 

728x90

'Study > ํ˜ผ๊ณต' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Swift] Escaping Closure  (2) 2024.04.28
[Swift] ๊ณ ์ฐจํ•จ์ˆ˜(map, filter, reduce)  (6) 2024.04.21
[Swift] Show Library ํ™œ์šฉ (Navigation Bar, Label, Button, Text Field)  (0) 2024.04.07