ARC

ARC ๋ชฉ์ฐจ

Swift์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ชจ๋ธ

๋ณต์Šต) ๊ฐ’ ํ˜•์‹๊ณผ ์ฐธ์กฐ ํ˜•์‹

  1. ๊ฐ’ ํ˜•์‹ (Value Type)

    • Baisic Type, ํŠœํ”Œ, ๊ตฌ์กฐ์ฒด, ์—ด๊ฑฐํ˜•, ์ปฌ๋ ‰์…˜ ๋“ฑ์ด ํ•ด๋‹น๋œ๋‹ค.

    • Stack ์˜์—ญ์— ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

    • ํ•„์š”์‹œ์—๋Š” ํ•ญ์ƒ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ฐ’์ด ๋ณต์‚ฌ๋˜์–ด ์ „๋‹ฌ๋œ๋‹ค.

    • ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด, Stackํ”„๋ ˆ์ž„์—์„œ ์•Œ์•„์„œ ์ œ๊ฑฐ๋˜๋ฏ€๋กœ ๋ณ„๋„๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ํ•  ํ•„์š” ์—†๋‹ค.

  2. ์ฐธ์กฐ ํ˜•์‹ (Reference Type)

    • ํด๋ž˜์Šค, ํด๋กœ์ €๊ฐ€ ํ•ด๋‹น๋œ๋‹ค.

    • ํ•„์š”์‹œ์— ํ•ญ์ƒ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฃผ์†Œ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. (Heap์˜ ์ฃผ์†Œ๋ฅผ Stack์— ์ €์žฅ)

    • Heap ์˜์—ญ์— ์‹ค์ œ ๊ฐ’๋“ค์ด ์ €์žฅ๋œ๋‹ค.

    • **RC(Reference Counting, ์ฐธ์กฐ ์นด์šดํŒ…)**์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

      • Swift์—์„œ ์‚ฌ์šฉํ•˜๋Š” ARC ๋ชจ๋ธ


๋ณต์Šต) ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ - ์ฝ”๋ฐํž™์Šค

  1. ์ฝ”๋“œ์˜์—ญ

    • CPU๊ฐ€ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์งˆ์  ๋ช…๋ น์–ด๋“ค์ด ๋ชจ์—ฌ์žˆ๋Š” ๊ณต๊ฐ„ (๋ชจ๋“  ์ฝ”๋“œ, ํ”„๋กœ๊ทธ๋žจ์ด ์กด์žฌ)

    • get Only

    • ์ฝ”๋“œ์˜์—ญ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋“ค์ด ๋ฐ์ดํ„ฐ, ํž™, ์Šคํƒ ์˜์—ญ์— ์ €์žฅ๋˜์–ด์žˆ๋‹ค.

      • ๋ฐ์ดํ„ฐ = ์ „์—ญ ๋ณ€์ˆ˜, ํƒ€์ž… ์†์„ฑ ๋“ฑ ๊ณตํ†ต์œผ๋กœ ๊ณต์œ ๋˜๋Š” ๋ฐ์ดํ„ฐ

      • ํž™ = ๋™์ ํ• ๋‹น์œผ๋กœ ํฌ๊ธฐ๊ฐ€ ํฌ๊ณ , ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ

      • ์Šคํƒ = ํ•จ์ˆ˜ ์‹คํ–‰์„ ์œ„ํ•œ ์ž„์‹œ ๊ณต๊ฐ„

  2. ๋ฐ์ดํ„ฐ ์˜์—ญ

    • ๊ณตํ†ต์œผ๋กœ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค.

      • ์ „์—ญ ๋ณ€์ˆ˜, ํƒ€์ž…์†์„ฑ์„ ์ €์žฅํ•œ๋‹ค.

      • ๋ถ•์–ด๋นต ํ‹€์ด ์ €์žฅ๋˜์–ด ์žˆ๋‹ค.

    • ์•ฑ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ์€ ๋ถˆ๋ณ€์˜ ์„ฑ์งˆ์„ ๊ฐ–๋Š”๋‹ค.

  3. ํž™ ์˜์—ญ

    • ์ธ์Šคํ„ด์Šค๋ฅผ ๋™์ ์œผ๋กœ ํ• ๋‹นํ•œ๋‹ค. (๋™์ ํ• ๋‹น)

      • ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธด ์‹œ๊ฐ„๋™์•ˆ ์ €์žฅํ•œ๋‹ค.

    • ํ•„์—ฐ์ ์œผ๋กœ ๋Š๋ฆด ์ˆ˜๋ฐ–์— ์—†๋‹ค.

    • ๊ด€๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ด ์•ฑ์ด ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋‹ค.

      • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํ˜„์ƒ(Memory Leak): ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ œ๊ฑฐ๋˜์ง€ ์•Š๋Š” ํ˜„์ƒ

      • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

  4. ์Šคํƒ ์˜์—ญ

    • ํ•จ์ˆ˜ ์‹คํ–‰์„ ์œ„ํ•œ ์ž„์‹œ์  ๊ณต๊ฐ„์ด๋‹ค.

    • ํฌ๊ธฐ๊ฐ€ ์ž‘๊ณ  ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค.

    • ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค.


์–ธ์–ด ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋ฒ•

  • ์ž๋ฐ”์˜ GC (Garbage Collector)

    • ๋Ÿฐํƒ€์ž„์— ํž™ ์˜์—ญ์„ ์ž๋™์œผ๋กœ ์Šค์บ”ํ•ด์„œ ์•Œ์•„์„œ ๊ด€๋ฆฌํ•ด์คŒ

    • ์Šค์บ”ํ•˜๋Š” ์†๋„๊ฐ€ ์žˆ์–ด์„œ ๋Š๋ ค์ง! (์–ธ์ œ ์–ด๋Š ์‹œ์ ์— ์ด๋ฃจ์–ด์ง€๋Š”์ง€๋Š” ์•Œ ์ˆ˜ ์—†์Œ)

  • objective - c

    • ์ฐธ์กฐ ์ˆซ์ž(RC)๋ฅผ ์„ธ๋Š” ๊ฒƒ์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ / ์ปดํŒŒ์ผ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ์‹œ์  ๊ฒฐ์ •

    • ์ˆ˜๋™์œผ๋กœ ์ˆซ์ž ์„ธ๋Š” ๊ฒƒ์ด MRC (๊ฐœ๋ฐœ์ž๊ฐ€ ์ˆ˜๋™์œผ๋กœ ๊ณ„์‚ฐ)

    • ์ž๋™์œผ๋กœ ์ˆซ์ž ์„ธ๋Š” ๊ฒƒ์ด ARC

      • ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์•Œ์•„์„œ ์ฝ”๋“œ๋ฅผ ์‹ฌ์–ด์คŒ โ†’ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์•Œ์•„์„œ ํ•ด์ฃผ๋Š”๊ฒŒ ์•„๋‹ˆ๊ณ  ์ˆซ์ž๋ฅผ ์ œ๋Œ€๋กœ ์„ธ ์ค€๋‹ค๋Š”๊ฒƒ์ž„! ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๊ฐ€ ์ž˜ ๋˜๋„๋ก, ์ด๋ก ์„ ์ž˜ ์•Œ๊ณ  ์‚ฌ์šฉํ•ด์•ผํ•จ.

  • Swift

    • ARC (Automatic RC)

      • ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค.


ARC ์ž‘๋™ ์›๋ฆฌ

  • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค ARC๋Š” ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค.

    • ์ธ์Šคํ„ด์Šค, ๊ด€๋ จ ํ”„๋กœํผํ‹ฐ ๊ฐ’, ์ธ์Šคํ„ด์Šค ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค.

  • ์ธ์Šคํ„ด์Šค๊ฐ€ ๋”์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฉด, ARC๋Š” ์‚ฌ์šฉ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น ํ•ด์ œํ•œ๋‹ค. โ†’ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜์ง€ ์•Š๋Š”๋‹ค.

    • ์ธ์Šคํ„ด์Šค์— ์ฐธ์กฐ๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์กด์žฌํ•œ๋‹ค๋ฉด, ARC๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น ํ•ด์ œํ•˜์ง€ ์•Š๋Š”๋‹ค. โ†’ ์ด๋ฅผ ์œ„ํ•ด ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ํ• ๋‹นํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค. ์ฐธ์กฐ๋Š” ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์œ ์ง€ํ•˜๊ณ , ๊ฐ•ํ•œ ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ํ•œ ํ• ๋‹น ํ•ด์ œ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ•ํ•œ ์ฐธ์กฐ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.


ARC์™€ MRC

  1. ARC(Automatic RC)

class Point {
    var x, y: Double
    func draw() {}
}

let point1 = Point(x: 0, y: 0)
let point2 = point1
point2.x = 5
//use point1
//use point2
  1. MRC

class Point {
    **var refCount: Int**
    var x, y: Double
    func draw() {}
}

let point1 = Point(x: 0, y: 0)
let point2 = point1
**retain(point2)**
point2.x = 5
//use point1
**release(point1)**
//user point2
**release(point2)**
  • ์ด์ „ ์–ธ์–ด๋“ค์€ MRC์™€ ๊ฐ™์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๋‹ค.

  • ํ˜„๋Œ€ ์–ธ์–ด์˜ ๊ฒฝ์šฐ ์ž๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•œ๋‹ค.

    • ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ retain() โ‡’ release() ํ•ด์ œ ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค๊ณ  ์ƒ๊ฐ

  • ์ด์ „ ์–ธ์–ด๋“ค์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ˆ˜๋™ ๊ด€๋ฆฌํ–ˆ์Œ (MRC)

  • ํ˜„๋Œ€ ์–ธ์–ด์˜ ๊ฒฝ์šฐ ์ž๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ชจ๋ธ ์‚ฌ์šฉ

    • Swift๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ retain()ํ• ๋‹น ์ฝ”๋“œ โ†’ release() ํ•ด์ œ ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค

    • ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์˜ ์•ˆ์ •์„ฑ์ด ์ฆ๊ฐ€๋œ๋‹ค.


ARC ๊ธฐ๋ฐ˜

  • ๋‚˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์†Œ์œ ์ž๊ฐ€ ์—†์œผ๋ฉด ํ•ด์ œ๋œ๋‹ค๋Š” ์›์น™์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

  1. ์†Œ์œ  ์ •์ฑ…

    • ํ•˜๋‚˜ ์ด์ƒ์˜ ์†Œ์œ ์ž๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€๋จ

  2. ์ฐธ์กฐ ์นด์šดํŒ…

    • ๋‚˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์†Œ์œ ์ž ์นด์šดํŒ…


ARC ๋™์ž‘

  • ์–ด๋–ป๊ฒŒ ์ž๋™ ์ฐธ์กฐ ์นด์šดํŒ…์ด ๋™์ž‘ํ•˜๋Š”๊ฐ€?

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

var soi: Person? = Person(name: "์ง€์›") // retain(soi), RC: 1
var reference: Person?
var reference = Person(name: "John") // retain(reference), RC: 2
soi = nil // release(soi), RC: 1
reference = nil // release(reference), RC: 0
  • ์˜ˆ์ „ ์–ธ์–ด์˜ ๊ฒฝ์šฐ ๋ชจ๋“  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐœ๋ฐœ์ž๋“ค์ด ์ˆ˜๋™ ๊ด€๋ฆฌํ–ˆ๋‹ค. (retain, release)

  • ํ˜„๋Œ€์  ์–ธ์–ด๋Š” ๋Œ€๋ถ€๋ถ„ ์ž๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋ฉฐ, Swift์˜ ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ retain() โ†’ release()์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค๊ณ  ๋ณด๋ฉด๋œ๋‹ค.

    • ํ”„๋กœ๊ทธ๋žจ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์•ˆ์ •์„ฑ์ด ์ฆ๊ฐ€ํ–ˆ๋‹ค.

์ฐธ์กฐ ์‚ฌ์ดํด๊ณผ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด์ด๋ž€?

  • ํด๋ž˜์Šค์˜ ์ €์žฅ์†์„ฑ์— ํŠน์ • ์ธ์Šคํ„ด์Šค๋ฅผ ์„œ๋กœ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    • Stack ์˜์—ญ์—์„œ๋Š” ์‚ฌ๋ผ์กŒ์ง€๋งŒ, RC๊ฐ€ 1๋กœ ์ €์žฅ๋˜์–ด์žˆ์–ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  • ์ฆ‰, ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด

    • ๋ณ€์ˆ˜์˜ ์ฐธ์กฐ์— nil์„ ํ• ๋‹นํ•ด๋„, ํ•ด์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

class Dog {
    var name: String
    var owner: Person

}

class Person {
    var name: String
    var pet: Dog?
}

var bory: = Dog? = Dog(name: "๋ณด๋ฆฌ")
var gildong: Person? = Person(name: "๊ธธ๋™)

// ์„œ๋กœ๊ฐ€ ์„œ๋กœ๋ฅผ ๊ฐ€๋ฆฌํ‚ด: **๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด (Strong Reference Cycle) ๋ฐœ์ƒ**
bori?.owner = gildong
gildong?.pet = bori

// ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ, but ์ƒ๊ฐํ•˜๊ธฐ ์‰ฝ์ง€ ์•Š์Œ
// bori?.owner = nil
// gildong?.pet = bory 

// **๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐœ์ƒ**
bori = nil
gildong = nil

ํ•ด๊ฒฐ ๋ฐฉ์•ˆ

  • ๊ฐ€๋ฆฌํ‚ค๋Š” ์ธ์Šคํ„ด์Šค์˜ RC์˜ ์ˆซ์ž๋ฅผ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ๋‚ด๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์„œ๋กœ์˜ ๊ฐ’์„ RC์— ์ ์šฉ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

    • ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ ๋„ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

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

    • ์†Œ์œ ์ž์— ๋น„ํ•ด ๋ณด๋‹ค ์งง์€ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ

      (๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค์˜ ์ˆ˜๋ช…์ด ์งง์€ ๊ฒฝ์šฐ. ์ฆ‰, ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋จผ์ € ํ• ๋‹น ํ•ด์ œ๋  ์ˆ˜ ์žˆ์„ ๋•Œ)

    • ๊ฐ’์ด ์—†์–ด์ง€๋ฉด nil์„ ์ž๋™ ํ• ๋‹น

      ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹น ํ•ด์ œ๋˜๋ฉด, ์ž๋™์œผ๋กœ nil๋กœ ์•ฝํ•œ ์ฐธ์กฐ๋กœ ์„ค์ •ํ•œ๋‹ค.

      ์ฐธ๊ณ ) ์ด ๋•Œ๋Š” ์†์„ฑ๊ฐ์‹œ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.

    • ์ƒ์ˆ˜๋กœ ์„ ์–ธํ•  ์ˆ˜ ์—†๋‹ค.

      ๋Ÿฐํƒ€์ž„์— ๊ฐ’์„ nil๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ๋ฝํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ๋ณ€์ˆ˜๋กœ ์„ ์–ธ๋œ๋‹ค.

  2. ๋ฏธ์†Œ์œ  ์ฐธ์กฐ (Unowned Reference)

    • RC๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์ฐธ์กฐ ํ•ด์ œ ์ˆœ์„œ๋ฅผ ์ฃผ์˜ํ•ด์•ผํ•จ.

    • Swift 5.3 ๋ฒ„์ „ ์ดํ›„, ์˜ต์…”๋„ ์„ ์–ธ์ด ๊ฐ€๋Šฅ

    • ๊ฐ’์ด ์—†์–ด์ ธ๋„ nil ์ž๋™ํ• ๋‹น ํ•˜์ง€ ์•Š์Œ

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

      • ํ•ญ์ƒ A ๊ฐ์ฒด๊ฐ€ ๋” ์งง๊ฒŒ ์‚ด ๋•Œ A๋Š” ๋น„์†Œ์œ  ์ฐธ์กฐ ์‚ฌ์šฉ

      • ์ฐธ์กฐ๊ฐ€ ํ•ญ์ƒ ํ• ๋‹น ํ•ด์ œ๋˜์ง€ ์•Š๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•œ๋‹ค๊ณ  ํ™•์‹ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ

      • ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹น ํ•ด์ œ๋œ ํ›„์— ๋ฏธ์†Œ์œ  ์ฐธ์กฐ์˜ ๊ฐ’์— ์ ‘๊ทผํ•˜๋ ค๊ณ ํ•˜๋ฉด, ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ ๋ฐœ์ƒ

  • ๊ณตํ†ต์ 

    • ๊ฐ€๋ฆฌํ‚ค๋Š” ์ธ์Šคํ„ด์Šค์˜ RC๋ฅผ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๊ฒŒ ํ•จ (์ธ์Šคํ„ด์Šค ์‚ฌ์ด์˜ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.)

    • ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผ์€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ธ์Šคํ„ด์Šค๋ฅผ ์œ ์ง€์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ์ฐจ์ด์ 

    • weak : ์†Œ์œ ์ž์— ๋น„ํ•ด ๋ณด๋‹ค ์งง์€ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง„ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

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

      โ†’ ์‹ค์ œ๋กœ๋Š” weak๋ฅผ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค. (๋น„์†Œ์œ ์ฐธ์กฐ๋Š” ํ•œ๋ฒˆ ๋” ๊ณ ๋ คํ•ด์•ผํ•˜๋‹ˆ๊นŒ)

  • unowned๊ฐ€ ์กฐ๊ธˆ ๋” ๋น ๋ฆ„!

    • ์‹ค์ œ๋กœ๋Š” unowned๋Š” ์ฝ”๋“œ๋ฅผ ๋” ์ž‘์„ฑํ•ด์•ผํ•˜๊ธฐ๋•Œ๋ฌธ์— weak์„ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ธฐ๋Š” ํ•จ

์˜ˆ์ œ ์ฝ”๋“œ

  1. ์•ฝํ•œ์ฐธ์กฐ

    class Dog {
        var name: String
        **weak** var owner: Person? // weak ํ‚ค์›Œ๋“œ -> ์•ฝํ•œ ์ฐธ์กฐ
    }
    
    class Person {
        var name: String
        **weak** var pet: Dog
    }
    • ์•ฝํ•œ์ฐธ์กฐ๋Š” ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด, ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ nil์„ ์ž๋™์œผ๋กœ ํ• ๋‹นํ•œ๋‹ค.

  2. ๋น„์†Œ์œ  ์ฐธ์กฐ (Unowned reference)

    class Dog {
        var name: String
        **unowned** var owner: Person? // swift 5.3 ์ด์ „์—๋Š” ์˜ต์…”๋„ ํƒ€์ž…์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์—ˆ์Œ.
    }
    
    class Person {
        var name: String
        **unowned** var pet: Dog? // ํ•œ ์ชฝ๋งŒ Unowned๋กœ ์„ ์–ธํ•ด๋„ ๋จ
    }
    
    gildong = nil
    **bori.owner = nil** // ์ด๋ ‡๊ฒŒ ํ• ๋‹นํ•ด์ค˜์•ผ๋ผ
    
    • ๋น„์†Œ์œ  ์ฐธ์กฐ์˜ ๊ฒฝ์šฐ, ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด nil๋กœ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์Œ.

      โ†’ nil๋กœ ํ• ๋‹นํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค. (์•ˆ ํ•˜๋ฉด ์•ฑ์ด ์ข…๋ฃŒ๋จ)

    • ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด, nil๋กœ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š๋Š”๋‹ค.

    // ์—๋Ÿฌ ๋ฐœ์ƒํ•˜๋Š” ์ผ€์ด์Šค
    gildong = nil
    bori.owner // nil๋กœ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์•„์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ
    
    // ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•
    gildong = nil
    bori.owner = nil // nil๋กœ ์žฌ์„ค์ • ํ•„์š”
    bori.owner // ์ ‘๊ทผ ๊ฐ€๋Šฅ

๊ฐ์ฒด ๋‚ด์—์„œ ํด๋กœ์ €์˜ ์‚ฌ์šฉ

๐Ÿ’ก (์š”์•ฝ) ํด๋กœ์ €์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด

  • ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์†์„ฑ์— ํด๋กœ์ € ํ• ๋‹น ํ›„, ํด๋กœ์ €์—์„œ ์ธ์Šคํ„ด์Šค ์บก์ฒ˜ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ

    โ†’ self๋ฅผ ์บก์ฒ˜ํ•˜์—ฌ ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค.

    โ†’ ํด๋กœ์ €๋„ ํด๋ž˜์Šค์™€ ๊ฐ™์€ ์ฐธ์กฐ ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!!

์ผ๋ฐ˜์ ์ธ ํด๋กœ์ €์˜ ์‚ฌ์šฉ

  • ํด๋กœ์ € ๋‚ด์—์„œ ๊ฐ์ฒด์˜ ์†์„ฑ ๋ฐ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผํ•  ๋•Œ **self** ํ‚ค์›Œ๋“œ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

    • ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

    • ๊ตฌ์กฐ์ฒด์˜ ๊ฒฝ์šฐ, self ์ƒ๋žต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    • Swift5.3 ์ดํ›„ [self]๋กœ ํ•  ์ˆ˜ ์žˆ์Œ

      self.name
      [self]
  • ์“ฐ๋ ˆ๋“œ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์“ฐ๋Š” ๊ฒฝ์šฐ, ์ƒˆ๋กœ์šด Stack์„ ๋งŒ๋“ค๊ฒŒ ๋œ๋‹ค.

    • ์—ฐ๊ด€๋œ ์ผ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์„ Stack ๋‚ด์—์„œ๋งŒ ์กด์žฌ! ๊ฐ ์“ฐ๋ ˆ๋“œ ๋ณ„ Stack

    • ๊ทธ๋Ÿฐ๋ฐ, code, data, heap์€ Stack๋ผ๋ฆฌ ๋‹ค๊ฐ™์ด ๊ณต์œ ํ•œ๋‹ค!

class Dog {
    var name = "choco"
    
    func doSomething() { // **ํด๋ž˜์Šค ๋‚ด ํด๋กœ์ €**
    
        // 2๋ฒˆ CPU์—์„œ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋ผ๊ณ  ์ƒ๊ฐ, ์ผ์˜ ๋ถ„๋ฆฌ, ๋™์‹œ ์ผ ์ฒ˜๋ฆฌ (๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ํด๋กœ์ €)
        // 2๋ฒˆ ์“ฐ๋ ˆ๋“œ๋Š” ์˜ค๋žซ๋™์•ˆ ์ €์žฅํ•ด์•ผํ•จ (์ƒˆ๋กœ์šด ์Šคํƒ์„ ๋งŒ๋“ค์–ด์„œ ์‹คํ–‰ํ•˜๋ฏ€๋กœ)
        DispatchQueue.global().async { // ๊ฐ•ํ•œ์ฐธ์กฐ ์‚ฌ์ดํด์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Œ.
            print("my name is \(**self.name**)")
        }
    
        // DispatchQueue.global().async { **[self]** in 
        //   print("my name is \(**name**)")
        // }
    }
}

var choco = Dog()
choco.doSomething()

//๋งŒ์•ฝ ๊ฐ•ํ•œ์ฐธ์กฐ ์‚ฌ์ดํด์ด ์ผ์–ด๋‚œ๋‹ค๋ฉด
DispatchQueue.global().async { [weak self] in // ๊ฐ•ํ•œ์ฐธ์กฐ ์‚ฌ์ดํด์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Œ.
    print("my name is \(**name**)")
}

ํด๋กœ์ €์˜ ์บก์ฒ˜๋ฆฌ์ŠคํŠธ - ๊ฐ•ํ•œ ์ฐธ์กฐ ์‚ฌ์ดํด ํ•ด๊ฒฐ (strong reference cycle)

  • ํด๋กœ์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์บก์ฒ˜ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•œ๋‹ค.

  • ํด๋กœ์ €์™€ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ•ํ•œ ์ฐธ์กฐ๋กœ, ์„œ๋กœ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๊ฒƒ = Strong Reference Cycle

    • ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ •์ƒ์ ์œผ๋กœ ํ•ด์ œ๋˜์ง€ ์•Š๊ณ , ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•œ๋‹ค.

  • ์บก์ฒ˜ ๋ฆฌ์ŠคํŠธ ๋‚ด์—์„œ ์•ฝํ•œ ์ฐธ์กฐ, ๋˜๋Š” ๋น„์†Œ์œ  ์ฐธ์กฐ๋ฅผ ์„ ์–ธํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค.

    • ์ฝ”๋“œ ๊ฐ„ ๊ด€๊ณ„์— ๋”ฐ๋ผ ์„ ํƒํ•ด์•ผํ•œ๋‹ค. (๋ณดํ†ต weak๊ณผ ์‚ฌ์šฉํ•œ๋‹ค)

Last updated