๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
3๏ธโƒฃ Swift/Swift ์ •๋ฆฌ

[Swift] ARC (2); ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜, Retain Cycle

by seolhee2750 2021. 10. 4.

์ €๋ฒˆ ๊ธ€์—์„œ๋Š” ARC์˜ ๊ฐœ๋…์— ๋Œ€ํ•ด ์•Œ์•„๋ดค๋Š”๋ฐ,

์˜ค๋Š˜์€ ARC๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜๋Š” ์ด์œ ์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•˜๊ณ 

๊ทธ๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ ํ•œ๋‹ค.

 

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณ„์† ์ ์œ ํ•˜๊ณ  ์žˆ๋Š” ํ˜„์ƒ์ด๋‹ค.

iOS์•ฑ์— ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์Œ“์ด๊ฒŒ๋˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•˜๊ณ , ๊ฒฐ๊ตญ์—” ์•ฑ์„ ์ฃฝ์ผ ์ˆ˜ ์žˆ๋‹ค.

 

์šฐ์„  ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์›์ธ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.

๐Ÿ“Ž ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐœ์ƒ ์›์ธ - Retain Cycle (๊ฐ•ํ•œ์ฐธ์กฐ ์ˆœํ™˜)

์ €๋ฒˆ ๊ธ€์—์„œ ๋งํ–ˆ๋“ฏ swift์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ARC๊ฐ€ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•ด์ฃผ๊ณ ,

ARC๋Š” ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์ ˆํ•œ ๋•Œ์— ํ•ด์ œ์‹œ์ผœ์ค€๋‹ค.

 

์ฐธ์กฐ์˜ ์ข…๋ฅ˜๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ,

์šฐ๋ฆฌ๊ฐ€ ํด๋ž˜์Šค ํƒ€์ž…์˜ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ณ€์ˆ˜, ์ƒ์ˆ˜ ๋“ฑ์„ ์„ ์–ธํ•  ๋•Œ

๋ณ„๋„์˜ ์‹๋ณ„์ž๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์œผ๋กœ '๊ฐ•ํ•œ์ฐธ์กฐ'๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.

(์ง€๊ธˆ๊นŒ์ง€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ var tmp = ~~ ์ด๋ ‡๊ฒŒ ์„ ์–ธํ–ˆ๋˜ ๊ฒƒ๋“ค ๋ชจ๋‘ ๊ฐ•ํ•œ์ฐธ์กฐ์˜€๋˜๊ฒƒ,,)

 

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

์ธ์Šคํ„ด์Šค๋ผ๋ฆฌ ์„œ๋กœ๊ฐ€ ์„œ๋กœ๋ฅผ ๊ฐ•ํ•œ ์ฐธ์กฐํ•  ๋•Œ๊ฐ€ ๋Œ€ํ‘œ์ !!!๐Ÿ’ฅ

์ด ๋ฌธ์ œ๋ฅผ ๋ฐ”๋กœ Retain Cycle, ๊ฐ•ํ•œ์ฐธ์กฐ ์ˆœํ™˜์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

์•„๋ž˜์— Retain Cycle์ด ์ผ์–ด๋‚˜๋Š” ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

class Example_A {
    var A: Example_B?
    init() {
        print("being initialized")
    }
    deinit {
        print("being deinitialized")
    }
}

class Example_B {
    var B: Example_A?
    init() {
        print("being initialized")
    }
    deinit {
        print("being deinitialized")
    }
}

var test1: Example_A? = Example_A() // Example_A ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "being initialized")
var test2: Example_B? = Example_B() // Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "being initialized")

test1?.A = test2 // Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 2
test2?.B = test1 // Example_A ์ฐธ์กฐ ํšŸ์ˆ˜ : 2

test1 = nil // Example_A ์ฐธ์กฐ ํšŸ์ˆ˜ : 1
test2 = nil // Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 1

Example_A, Example_B ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ–ˆ๊ณ , ๊ฐ ํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐํ•˜๋Š” test1, test2 ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ–ˆ๋‹ค.

 

์ฒ˜์Œ ์ฐธ์กฐ๋ฅผ ์ •์˜ํ–ˆ์„ ๋•Œ being initialized๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ถœ๋ ฅ๋จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ ,

์ด ๋•Œ Example_A์™€ Example_B ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” 1์”ฉ ์ฆ๊ฐ€๋œ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ์ถ”๊ฐ€๋กœ, ๋‘ ๋ณ€์ˆ˜์˜ ๊ฐ๊ฐ ์ฐธ์กฐํ•˜๋Š” ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์„œ๋กœ์˜ ์ฐธ์กฐ ํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ํ–ˆ๋‹ค.

์ด ๋•Œ ๋‘ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ๋˜๋‹ค์‹œ 1์”ฉ ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋œ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ์ฃผ๋Š” ๊ฒƒ๊นŒ์ง€์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค.

์ด์ œ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ํ•˜๋‚˜์”ฉ ๊ฐ์†Œ์‹œ์ผœ๋ณด์ž.

 

test1 ๋ณ€์ˆ˜์— nil์„ ํ• ๋‹นํ•˜๋ฉด test1์ด ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์ธ Example_A์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” 1 ๊ฐ์†Œํ•œ๋‹ค.

๐Ÿ‘‰ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ 0๊นŒ์ง€ ๊ฐ์†Œ์‹œ์ผœ์ค˜์•ผ ํ•˜๋Š”๋ฐ,

์ด๋ ‡๊ฒŒ ๋˜๋ฉด test1 ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด Example_A์˜ ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ๊ฐ์†Œ์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” test2๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ B ํ”„๋กœํผํ‹ฐ๋กœ Example_A๋ฅผ ์ฐธ์กฐํ•ด๋†จ์œผ๋ฏ€๋กœ..!!!

์ด ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด Example_A์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์ค„์—ฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„์ง์€ ๋ฌธ์ œ ์—†์Œ.!

 

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ test2์—๋„ nil์„ ํ• ๋‹นํ•ด๋ฒ„๋ฆฌ๋ฉด ์ด ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.โ—๏ธ

1) ์œ ์ผํ•˜๊ฒŒ Example_A ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๊ฐ€ ์‚ฌ๋ผ์ง
2) nil ํ• ๋‹น์œผ๋กœ Example_B ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜ 1์ด ๊ฐ์†Œ๋˜์ง€๋งŒ, ๋”์ด์ƒ ๊ฐ์†Œ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๋Š” ์—†์Œ

 

๋”ฐ๋ผ์„œ Example_A, Example_B ์ธ์Šคํ„ด์Šค ๋ชจ๋‘ ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ 1์ธ์ฑ„๋กœ

์ƒˆ๋กœ์šด ์ฐธ์กฐ ํšŸ์ˆ˜์˜ ๊ฐ์†Œ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋˜์—ˆ์œผ๋ฏ€๋กœ, ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ๋ฐฉ๋ฒ•์ด ์‚ฌ๋ผ์ง€๊ฒŒ๋œ๋‹ค.

๐Ÿ‘‰ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ๋‚จ๊ฒจ๋‘” ์ฑ„๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ์ข€๋น„์ฒ˜๋Ÿผ ๋‚จ์•„์žˆ๊ฒŒ ๋จ. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜!!!

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฌผ๋ก  ์šฐ๋ฆฌ๊ฐ€ ์ข€ ๋” ์‹ ๊ฒฝ์„ ์จ์„œ..!

์•„๋ž˜์™€๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ๋ง‰์ง€ ์•Š๊ฒŒ, ์ˆœ์ฐจ์ ์œผ๋กœ nil์„ ํ• ๋‹นํ•ด์ฃผ๋ฉด ๊ฐ€๋Šฅ์€ํ•˜๋‹ค.

test1?.A = nil
test1 = nil

test2?.B = nil
test2 = nil

 

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹ค์ˆ˜ํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ์ปค์ง€๊ณ , ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์งˆ ๊ฒฝ์šฐ์—” ํ•ด๊ฒฐํ•˜๊ธฐ ์–ด๋ ค์šธ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ด์ œ ์ด ๋ฌธ์ œ๋ฅผ ์ข€ ๋” ํšจ๊ณผ์ ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ด์•ผ๊ฒ ์ง€,.!


๐Ÿ“Ž Retain Cycle ํ•ด๊ฒฐ (1) - Weak Reference (์•ฝํ•œ์ฐธ์กฐ)

์•ฝํ•œ์ฐธ์กฐ๋Š” ๊ฐ•ํ•œ์ฐธ์กฐ์™€ ๋‹ฌ๋ฆฌ, ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

์ด ์•ฝํ•œ์ฐธ์กฐ๋Š” ์–ด๋–ป๊ฒŒ ์“ฐ๋Š”๊ฑด์ง€, ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ฝ”๋“œ๋กœ ํ™•์ธํ•ด๋ณด์ž.

class Example_A {
    var A: Example_B?
    init() {
        print("being initialized")
    }
    deinit {
        print("being deinitialized")
    }
}

class Example_B {
    weak var B: Example_A?
    init() {
        print("being initialized")
    }
    deinit {
        print("being deinitialized")
    }
}

var test1: Example_A? = Example_A() // Example_A ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "being initialized")
var test2: Example_B? = Example_B() // Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "being initialized")

test1?.A = test2 // Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 2
test2?.B = test1 // Example_A ์ฐธ์กฐ ํšŸ์ˆ˜ : 1

test1 = nil // Example_A ์ฐธ์กฐ ํšŸ์ˆ˜ : 0, Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "being deinitialized")
print(test2?.B) // Prints "nil"
test2 = nil // Example_B ์ฐธ์กฐ ํšŸ์ˆ˜ : 0 (Prints "being deinitialized")

์œ„์—์„œ ๊ฐ•ํ•œ์ฐธ์กฐ๋กœ ์ธํ•œ Retain Cycle ์˜ˆ์ œ์™€ ๋™์ผํ•˜๊ฒŒ ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•˜๊ณ  ์ฐธ์กฐํ–ˆ๋‹ค.

test1, test2๋กœ ํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐํ•œ ๋ถ€๋ถ„๊นŒ์ง€๋Š” ์œ„์˜ ์˜ˆ์ œ์™€ ๊ฐ™์€๋ฐ, ๊ทธ ์•„๋ž˜๋ถ€ํ„ฐ๋Š” ์กฐ๊ธˆ์”ฉ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค.

 

test2?.B์— test1์„ ํ• ๋‹นํ–ˆ์„ ๋•Œ์˜ ์ฃผ์„์„ ๋ณด๋ฉด, Example_A์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ์ฆ๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ ์ด์œ ๋Š” test2๊ฐ€ ์ฐธ์กฐํ•˜๋Š” Example_B์˜ ํ”„๋กœํผํ‹ฐ B๋ฅผ

weak ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ Example_A๋ฅผ ์•ฝํ•œ์ฐธ์กฐํ•˜๊ฒŒ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์œ„์—์„œ ๋งํ–ˆ๋“ฏ ์•ฝํ•œ์ฐธ์กฐ๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐํšŸ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.๐Ÿ’ฅ

 

๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์— ๊ฐ ๋ณ€์ˆ˜์— nil์„ ํ• ๋‹นํ•˜๋ฉฐ ์ธ์Šคํ„ด์Šค ํ•ด์ œ๋ฅผ ์‹œ์ž‘ํ•˜๋Š”๋ฐ,

test1์— nil์„ ํ• ๋‹นํ•œ ๋ถ€๋ถ„์„ ํ™•์ธํ•˜๋ฉด Example_A์™€ Example_B์˜ ์ฐธ์กฐ ํšŸ์ˆ˜ ๋ชจ๋‘ ๊ฐ์†Œํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Q) Example_A๋ฅผ ์ฐธ์กฐํ•˜๋Š” test1์—๋งŒ nil์„ ํ• ๋‹นํ–ˆ์„ ๋ฟ์ธ๋ฐ ์™œ Example_B๊นŒ์ง€ ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ ๊ฐ์†Œํ–ˆ์„๊นŒ?

๊ทธ ์ด์œ ๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋˜๊ฒŒ ๋‹น์—ฐํ•œ๋ฐ,

Example_A ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๋ฉด ์ž์—ฐ์Šค๋ ˆ Example_A์˜ ํ”„๋กœํผํ‹ฐ์ธ A ๋˜ํ•œ ์—ญํ• ์ด ๋๋‚˜๊ฒŒ ๋˜๊ณ ,
A๋Š” Example_B๋ฅผ ๋”์ด์ƒ ๊ฐ•ํ•œ์ฐธ์กฐํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ Example_B์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๊นŒ์ง€ ๊ฐ์†Œ๋˜๋Š”๊ฒƒโ—๏ธ

๐Ÿ‘‰์ •๋ฆฌํ•˜์ž๋ฉด, ์–ด๋–ค ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๋ฉด ๊ทธ์™€ ๋™์‹œ์—

๊ทธ ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ•ํ•œ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๊นŒ์ง€ 1 ๊ฐ์†Œํ•˜๊ฒŒ๋œ๋‹ค.

 

์ถ”๊ฐ€๋กœ, ์ด ๋•Œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋Š” ์•ฝํ•œ์ฐธ์กฐ์˜ ํŠน์ง•์ด ํ•˜๋‚˜ ์žˆ๋‹ค.

์ด ๋ถ€๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด test2?.B์˜ ๊ฐ’์ด nil์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๊ทธ ์ด์œ ๋Š”

Example_A ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋จ์œผ๋กœ ์ธํ•ด ํ”„๋กœํผํ‹ฐ B๋Š” ์ฐธ์กฐํ•˜๋Š” ๋Œ€์ƒ์ด ์‚ฌ๋ผ์ง€๊ฒŒ ๋˜์—ˆ๊ณ ,

B๋Š” ์•ฝํ•œ์ฐธ์กฐ๋ฅผ ํ•˜๋ฏ€๋กœ ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜์—ˆ์œผ๋‹ˆ ์ž๋™์œผ๋กœ nil์„ ํ• ๋‹นํ•œ ๊ฒƒ์ด๋‹ค.

+ ๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ ๋˜ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ ์€,

์•ฝํ•œ์ฐธ์กฐ๋ฅผ ํ•˜๋ฉด ์œ„์™€๊ฐ™์ด ๋‚ด๊ฐ€ ๋ชจ๋ฅด๋Š” ์‚ฌ์ด ์ฐธ์กฐํ•˜๊ณ ์žˆ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ด์ œ๋˜์–ด์žˆ์„ ์ˆ˜ ์žˆ๊ณ ,
๊ทธ ๊ฒฝ์šฐ์—๋Š” ์ž๋™์œผ๋กœ nil์ด ํ• ๋‹น๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ๋Š” 'nil'๋กœ '๋ณ€ํ• '์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์•ฝํ•œ์ฐธ์กฐ๋ฅผ ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ ๊ผญ ์˜ต์…”๋„ ๋ณ€์ˆ˜๋กœ ์„ ์–ธ๋˜์–ด์•ผํ•œ๋‹ค.๐Ÿ’ฅ

๐Ÿ‘‰์ •๋ฆฌ! ์•ฝํ•œ์ฐธ์กฐ๋ฅผ ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ์ž์‹ ์ด ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๋ฉด

์ž๋™์œผ๋กœ nil์„ ํ• ๋‹นํ•˜๋ฉฐ, ๊ผญ ์˜ต์…”๋„ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•ด์•ผํ•œ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์•ฝํ•œ์ฐธ์กฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•จ์œผ๋กœ ์ธํ•ด ๊ฐ•ํ•œ์ฐธ์กฐ ์ˆœํ™˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฐฉ๋ฒ•์ด ์•ฝํ•œ์ฐธ์กฐ ํ•˜๋‚˜๋งŒ ์žˆ๋Š”๊ฒƒ์€ ์•„๋‹˜!


๐Ÿ“Ž Retain Cycle ํ•ด๊ฒฐ (2) - Unowned Reference (๋ฏธ์†Œ์œ ์ฐธ์กฐ)

๋ฏธ์†Œ์œ ์ฐธ์กฐ๋˜ํ•œ ์•ฝํ•œ์ฐธ์กฐ์ฒ˜๋Ÿผ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š๋Š” ์ฐธ์กฐ ๋ฐฉ๋ฒ•์ด๋‹ค.

์ด ๋‘˜์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€,

๋ฏธ์†Œ์œ ์ฐธ์กฐ์˜ ๊ฒฝ์šฐ ๋‚ด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ผญ ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•  ๊ฒƒ์ด๋ผ๋Š” ์ „์ œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

๋ง๋กœ๋Š” ๋„ˆ๋ฌด ์–ด๋ ค์šฐ๋‹ˆ,, ์ฝ”๋“œ๋กœ ํ™•์ธํ•ด๋ณด์ž!

import Foundation

class Person {
    let name: String
    var car: Car? // ์‚ฌ๋žŒ์€ ์ฐจ๋ฅผ ๊ฐ€์ง€์ง€ ์•Š์•„๋„ ๋จ => ๊ฐ•ํ•œ ์ฐธ์กฐ, ์˜ต์…”๋„๋กœ ์„ ์–ธ
    
    init(name: String) {
        self.name = name
        print("\(name) being initialized")
    }
    
    deinit {
        print("\(name) being deinitialized")
    }
}

class Car {
    let name: String
    unowned var owner: Person // ์ฐจ๋Š” ๊ผญ ์ฃผ์ธ์ด ์žˆ์–ด์•ผ ํ•จ => ๋ฏธ์†Œ์œ  ์ฐธ์กฐ๋กœ ์„ ์–ธ
    
    init(name: String, owner: Person) {
        self.name = name
        self.owner = owner
        print("\(name) being initialized")
    }
    
    deinit {
        print("\(name) being deinitialized")
    }
}

var seolhee: Person? = Person(name: "seolhee") // Person ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "seolhee being initialized")

if let person: Person = seolhee {
    person.car = Car(name: "tivoli", owner: person) // Car ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜ : 1 (Prints "tivoli being initialized")
    // Person ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜ : 1
}

seolhee = nil // Person ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜ : 0, Car ์ธ์Šคํ„ด์Šค ์ฐธ์กฐ ํšŸ์ˆ˜ : 0 (Prints "seolhee being deinitialized", "tivoli being deinitialized")

์ด ๋ฏธ์†Œ์œ ์ฐธ์กฐ๋Š” ์ด๋ฆ„์ฒ˜๋Ÿผ '์†Œ์œ '์˜ ๊ด€๊ณ„๋ฅผ ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•˜๋‹ค.

๋‚˜๋Š” ์ฐจ์™€ ๊ทธ ์ฐจ์ฃผ์˜ ๊ด€๊ณ„๋ฅผ ์˜ˆ์‹œ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ, ์‚ฌ๋žŒ์€ ์ฐจ๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ฐจ๋Š” ์‚ฌ๋žŒ์ด ๊ผญ ํ•„์š”ํ•˜๋‹ค.

๋”ฐ๋ผ์„œ Car ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Person ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ผญ ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•ด์•ผ๋งŒ ํ•œ๋‹ค.!!

 

์œ„์˜ ์ด์•ผ๊ธฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž. ๋จผ์ € ํด๋ž˜์Šค ๊ตฌํ˜„๋ถ€!

(1) Person ํด๋ž˜์Šค์˜ car ํ”„๋กœํผํ‹ฐ๋Š” Car ํด๋ž˜์Šค๋ฅผ ๊ฐ•ํ•œ์ฐธ์กฐํ•˜๋ฉฐ ์˜ต์…”๋„๋กœ ์„ ์–ธํ–ˆ๋‹ค.

์‚ฌ๋žŒ์€ ์ฐจ๋ฅผ ๊ฐ€์งˆ์ˆ˜๋„, ๊ฐ€์ง€์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ ์˜ต์…”๋„๋กœ ์ •์˜ํ–ˆ์œผ๋ฉฐ

์ฐจ๋ฅผ ํ•œ ๋ฒˆ ๊ฐ€์ง„ ํ›„์—๋Š” ํ•จ๋ถ€๋กœ ์žƒ์–ด๋ฒ„๋ฆฌ๋ฉด ์•ˆ๋˜๋ฏ€๋กœ ๊ฐ•ํ•œ์ฐธ์กฐ๋ฅผ ํ•˜๋„๋ก ํ–ˆ๋‹ค.

(2) Car ํด๋ž˜์Šค์˜ owner ํ”„๋กœํผํ‹ฐ๋Š” unowned ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋ฏธ์†Œ์œ ์ฐธ์กฐํ–ˆ๋‹ค.

์ฐจ๋Š” ์†Œ์œ ์ฃผ๊ฐ€ ๊ผญ ์žˆ์–ด์•ผ ์กด์žฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์˜ต์…”๋„๋กœ ์ •์˜ํ•˜์ง€ ์•Š์•˜๊ณ ,

์ฐจ๊ฐ€ ์žˆ๋Š” ํ•œ ๋‹น์—ฐํžˆ ์†Œ์œ ์ฃผ๋„ ์กด์žฌํ•œ๋‹ค๋Š” ํ™•์‹ ์ด ์žˆ์œผ๋ฏ€๋กœ ๋ฏธ์†Œ์œ ์ฐธ์กฐํ•˜๊ฒŒ ํ–ˆ๋‹ค.

 

ํด๋ž˜์Šค ๊ตฌํ˜„ ํ›„ ๊ฐ€์žฅ ๋จผ์ € Person์„ ์ฐธ์กฐํ•˜๋Š” seolhee๋ฅผ ์ •์˜ํ–ˆ๊ณ , Person ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” 1 ์ฆ๊ฐ€ํ•œ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  if let ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ Person ์ธ์Šคํ„ด์Šค๊ฐ€ ์กด์žฌํ•˜๋ฉด! Car์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑํ•ด์ฃผ์—ˆ๋‹ค.

(Person ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€ ์žˆ์–ด์•ผ๋งŒ Car์ธ์Šคํ„ด์Šค ๋˜ํ•œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ!๐Ÿ’ฅ)

์ด ๋•Œ Car ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” 1 ์ฆ๊ฐ€ํ•˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€๊ฒŒ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด ๋•Œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€, Car์˜ ownerํ”„๋กœํผํ‹ฐ๊ฐ€ Person์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ๋˜์—ˆ์ง€๋งŒ

๋ฏธ์†Œ์œ ์ฐธ์กฐํ–ˆ์œผ๋ฏ€๋กœ Person ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ์ฆ๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์•ฝํ•œ์ฐธ์กฐ์™€์˜ ๊ณตํ†ต์ !

 

๋งˆ์ง€๋ง‰์œผ๋กœ๋Š” seolhee ๋ณ€์ˆ˜์— ๋‹ค์‹œ nil์„ ํ• ๋‹นํ•ด์ฃผ์—ˆ๋‹ค.

์ด ๋•Œ ๋‹น์—ฐํžˆ Person ์ธ์Šคํ„ด์Šค๋Š” ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ 1 ๊ฐ์†Œํ•˜๋ฉด์„œ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜๊ณ 

Car ์ธ์Šคํ„ด์Šค์˜ ๊ฒฝ์šฐ ์•ฝํ•œ์ฐธ์กฐ ๋ถ€๋ถ„์—์„œ ๊ณต๋ถ€ํ•œ๋Œ€๋กœ, Person ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ด์ œ๋จ์— ๋”ฐ๋ผ

Person์˜ ํ”„๋กœํผํ‹ฐ car๊ฐ€ ๊ฐ•ํ•œ์ฐธ์กฐํ•˜๋Š” Car ์ธ์Šคํ„ด์Šค ๋˜ํ•œ ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ 1 ๊ฐ์†Œํ•˜๊ฒŒ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ Car๊นŒ์ง€ ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ์™„๋ฃŒ!

 

์ด๋ ‡๊ฒŒ ๋ฏธ์†Œ์œ ์ฐธ์กฐ๋ฅผ ์ด์šฉํ•˜๋ฉด

์˜ˆ์ œ์ฒ˜๋Ÿผ ์‚ฌ๋žŒ์ด ์—†์–ด์ง€๋ฉด ์ฐจ๋„ ์—†์–ด์ ธ์•ผ ํ•˜๋Š” ์ด๋Ÿฐ ์ƒํ™ฉ์„ ์‰ฝ๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ณ 

๊ฐ•ํ•œ์ฐธ์กฐ ์ˆœํ™˜ ๋ฌธ์ œ๋„ ํ”ผํ•ด๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค.โ—๏ธ


๐ŸŒŸ ์ •๋ฆฌ

Retain Cycle์€ ๊ฐ•ํ•œ์ฐธ์กฐ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋กœ,

์ด๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ณ  ์•ฑ์— ์น˜๋ช…์ ์ธ ์˜ํ–ฅ์„ ๋ผ์น  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ•ํ•œ์ฐธ์กฐ ์ˆœํ™˜ ๋ฌธ์ œ๋Š” ์•ฝํ•œ์ฐธ์กฐ๋‚˜ ๋ฏธ์†Œ์œ ์ฐธ์กฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐ์ด๊ฐ€๋Šฅํ•œ๋ฐ,

์ฐธ์กฐ๋ฅผ ํ•˜๋ฉด ๋ฌด์กฐ๊ฑด ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ 1 ์ฆ๊ฐ€๋˜๋Š” ๊ฐ•ํ•œ ์ฐธ์กฐ์˜ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์•ฝํ•œ์ฐธ์กฐ์™€ ๋ฏธ์†Œ์œ ์ฐธ์กฐ๋Š” ๋ชจ๋‘ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€์•Š์œผ๋ฉฐ,

์•ฝํ•œ์ฐธ์กฐ๋Š” ๋‚ด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜์—ˆ์„ ๊ฒฝ์šฐ

์ž๋™์œผ๋กœ nil์„ ํ• ๋‹นํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์กฐ๊ฑด ์˜ต์…”๋„ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•ด์•ผํ•˜๊ณ ,

๋ฏธ์†Œ์œ ์ฐธ์กฐ๋Š” ๋‚ด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฌด์กฐ๊ฑด ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ• ๊ฒƒ์ด๋ผ๋Š” ์ „์ œ ํ•˜์— ์‚ฌ์šฉํ•˜๋Š” ์ฐธ์กฐ์ด๋ฏ€๋กœ

์˜ต์…”๋„ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

 


์ฐธ๊ณ 

  • ๐Ÿ“– ์Šค์œ„ํ”„ํŠธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋Œ“๊ธ€