๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS/๐Ÿ˜ถ ๊ถ๊ธˆ์ฆ

[iOS] ARC_๊ฐ์ฒด ์ˆ˜๋ช…, weak์™€ unowned ์ฐจ์ด

by MINT09 2024. 3. 21.

 

Swift์—์„œ struct์™€ ๊ฐ™์€ ๊ฐ’ ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ, class์™€ ๊ฐ™์€ ์ฐธ์กฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฐธ์กฐ ์นด์šดํŠธ, Reference Count๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์• ํ”Œ์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๊ฑฐ๋‚˜, ์ฐธ์กฐํ•  ๋•Œ ์นด์šดํŠธ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ์‚ฌ์šฉ์„ ์™„๋ฃŒํ•˜๋ฉด ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.

Objective -C์—์„œ๋Š” ์ด๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ด€๋ฆฌํ–ˆ์—ˆ๊ณ , ๊ทธ๊ฒƒ์„ MRC Manual Reference Counting ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ Swift์—์„œ๋Š” ์ง์ ‘์ ์œผ๋กœ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๊ณ  ํ•ด์ œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค. complier๊ฐ€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ž๋™์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„์„ ํ†ตํ•ด ์•Œ์•„์„œ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ํ•ด์ฃผ๋Š”๋ฐ ์ด๋ฅผ ARC Automatic Reference Counting์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

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

๋•Œ๋ฌธ์— ์ €ํฌ๋Š” ์ด ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์ด ๋๋‚ฌ๋Š”์ง€๋ฅผ ๊ด€์ฐฐํ•˜๊ธฐ ์œ„ํ•ด ๊ด€์ฐฐ๋œ ๊ฐ์ฒด ์ˆ˜๋ช…(Observed Object’s lifetime)์„ ์‚ฌ์šฉํ•˜๊ณ ๋Š” ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” Weak, Unowned, Deinit๊ณผ ๊ฐ™์€ ํ‚ค์›Œ๋“œ๋“ค์ด ์žˆ๋Š”๋ฐ ํŠนํžˆ Weak์™€ Unowned๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์นด์šดํŠธ๋ฅผ ์˜ฌ๋ฆฌ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

weak & unowned

๋‹ค๋งŒ ์ด๋“ค์€ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์˜ฌ๋ฆฌ์ง€ ์•Š์•„์„œ Weak๋‚˜ Unowned๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋™์•ˆ ์ฐธ์กฐ๋œ ๊ฐœ์ฒด์˜ ํ• ๋‹น์ด ์ทจ์†Œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด Swift Runtime์€ weak์— ๋Œ€ํ•œ access๋ฅผ nil๋กœ, unowned์— ๋Œ€ํ•œ access๋ฅผ trap์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์™œ ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ์š”?

์• ์ดˆ์— ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋  ๋•Œ๋ถ€ํ„ฐ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. weak๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํฌ์ธํ„ฐ๋Š” unowned์ฒ˜๋Ÿผ ์ €์žฅ๋˜์–ด ์žˆ๋Š” HeapObject๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ object Pointer๋ฅผ ์ง€๋‹ˆ๊ณ  ์žˆ๋Š” SideTable์ด๋ผ๋Š” ๊ฒƒ์ด ์ƒ์„ฑ๋˜๋ฉด์„œ HeapObjectSideTableEntry๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Side Table์€ weak ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์˜€์„ ๋•Œ, Strong๊ณผ unowned์˜ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋˜์—ˆ์„ ๋•Œ, ๊ฐ์ฒด๊ฐ€ ๊ด€๋ จํ•˜์—ฌ ์ถ”๊ฐ€์ ์ธ ๊ณต๊ฐ„์ด ํ•„์š”ํ•  ๋•Œ ์ƒ๊ธฐ๋Š” ๊ฒƒ์œผ๋กœ ์Šค๋ ˆ๋“œ ๊ฐ„์˜ Race Condition์„ ๋ง‰๊ธฐ ์œ„ํ•ด one-way Operation์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

๋•Œ๋ฌธ์— ์ฐธ์กฐ๋œ ๊ฐ์ฒด์˜ ํ• ๋‹น์ด ์ทจ์†Œ๋˜์–ด Deinited ์ƒํƒœ๊ฐ€ ๋˜๋”๋ผ๋„ side table์ด ๋‚จ์•„์žˆ๊ธฐ ๋•Œ๋ฌธ์— nil์„ ๋ฐ˜ํ™˜๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋ ‡๊ฒŒ ๋ฐ›๋Š”๋‹ค๊ณ  ๊ฐ’์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. side table์€ ์–ด๋””๊นŒ์ง€๋‚˜ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋กœ ์ถ”๊ฐ€์ ์ธ ๊ณต๊ฐ„์ผ ๋ฟ์ด๊ธฐ์— ํ”์ ์ด ์žˆ๋Š” ๊ฒƒ์ผ ๋ฟ, ํ•ด๋‹น ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์กด์žฌํ•˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค๋งŒ ์ด๋Ÿฌํ•œ ๊ด€์ฐฐ๋œ ๊ฐ์ฒด ์ˆ˜๋ช…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•ž์„œ ๋งํ–ˆ๋“ฏ ๊ฐ์ฒด ์ˆ˜๋ช…์„ ๋ณด์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฝค๋‚˜ ์œ„ํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ARC WWDC์˜ ์˜ˆ์ œ์—์„œ ๋ณด๋ฉด test ํ•จ์ˆ˜์˜ ๋งˆ์ง€๋ง‰์— account.printSummary()๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋Š” ์šฐ์—ฐํ•œ ์ผ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. traveler ๊ฐ์ฒด์˜ ๋งˆ์ง€๋ง‰ ์‚ฌ์šฉ์ด ํ•ด๋‹น ํ•จ์ˆ˜ ์ด์ „์ด๋ผ, ๊ฐ์ฒด ์ˆ˜๋ช…์ด ๋๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ œ๋Œ€๋กœ ์ž‘๋™ํ•œ๋‹ค๋ฉด, ์ด๋Š” nil๋กœ ๋ณ€๊ฒฝ๋˜์–ด crash๊ฐ€ ๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Solution

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

1. withExtendedLifetime()

withExtendedLifetime()์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์„ ๋ช…์‹œ์ ์œผ๋กœ ์—ฐ์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ์žฅํ•˜๊ณ  ์‹ถ์€ ์ฝ”๋“œ๋ฅผ ํด๋กœ์ €์— ๋„ฃ๊ฑฐ๋‚˜, ํ˜น์€ ์—ฐ์žฅํ•˜๊ณ  ์‹ถ์€ ๋ผ์ธ ๋ฐ‘์— ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. defer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ฐ์ฒด ์ˆ˜๋ช…์„ ์—ฐ์žฅ์‹œํ‚ค๋Š” ๊ฒƒ๋„ ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์ด๊ฒ ์ฃ .

์ด๋Š” ๋งˆ์น˜ MRC์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ฑ…์ž„์ด ์š”๊ตฌ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— ๊ด€์ฐฐ๋œ ๊ฐ์ฒด ์ˆ˜๋ช…์œผ๋กœ ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์นซํ•˜๋‹ค๊ฐ„ ์œ ์ง€๊ด€๋ฆฌ ๋น„์šฉ์ด ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. ๋” ๋‚˜์€ API๋กœ ์žฌ์„ค๊ณ„

ํ˜น์€ ์• ์ดˆ๋ถ€ํ„ฐ ๋ฒ„๊ทธ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๋ณ€๊ฒฝ

ARC WWDC์—์„œ๋Š” ์• ์ดˆ๋ถ€ํ„ฐ weak๋‚˜ unowned ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ผ ์—†์ด class ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด ์žˆ์„์ง€๋„ ๋ชจ๋ฅด๋Š” ๋ฒ„๊ทธ๋“ค์„ ์ œ๊ฑฐํ•˜๋Š” ํ™•์‹คํ•œ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ˆœ๊ฐ„๋“ค์ด ์žˆ์œผ๋‹ˆ ๋งŒ๋“ค์–ด์กŒ์„ ํ…Œ๋‹ˆ ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž!๋Š” ์•„๋‹Œ ๊ฒƒ ๊ฐ™๊ตฌ์š”. ์ด๋Ÿฌํ•œ ์‚ฌํ•ญ๋“ค์„ ์ž˜ ์ƒ๊ฐํ•˜๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

https://developer.apple.com/videos/play/wwdc2021/10216/

 

ARC in Swift: Basics and beyond - WWDC21 - Videos - Apple Developer

Learn about the basics of object lifetimes and ARC in Swift. Dive deep into what language features make object lifetimes observable,...

developer.apple.com

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/automaticreferencecounting#app-top

 

Documentation

 

docs.swift.org

https://github.com/apple/swift/blob/main/stdlib/public/SwiftShims/swift/shims/RefCount.h

 

swift/stdlib/public/SwiftShims/swift/shims/RefCount.h at main · apple/swift

The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.

github.com

https://shubhamchawla00.medium.com/memory-management-on-ios-ad2244b49b20

 

Memory management on iOS

Memory Management

shubhamchawla00.medium.com

https://jeonyeohun.tistory.com/373

 

[Swift] strong, weak, unowned์˜ ๋น„๋ฐ€

๋ž˜ํผ๋Ÿฐ์Šค ์นด์šดํŠธ ์•ˆ๋…•ํ•˜์„ธ์š”! ์˜ค๋Š˜์€ swift์—์„œ ๋ž˜ํผ๋Ÿฐ์Šค ์นด์šดํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ๋ธ”๋กœ๊ทธ์—์„œ weak๊ณผ unowned์˜ ์ฐจ์ด๋ฅผ Optional์˜ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ผ๊ณ  ๋งํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์‚ฌ

jeonyeohun.tistory.com