์˜ค๋ž˜ ๊ธฐ๋‹ค๋ ธ๋‹ค. ARC๊ฐ€ ๋ฌด์—‡์ผ๊นŒ? ์ž๋ฐ”์˜ Garbage Collector์™€๋Š” ๋ฌด์—‡์ด ๋‹ค๋ฅผ๊นŒ? ์žฅ๋‹จ์ ์€ ๋ฌด์—‡์ผ๊นŒ? ์–ด๋–ค ์›๋ฆฌ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ผ๊นŒ? ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ ์€ ๋ฌด์—‡์ผ๊นŒ? ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์ด๋Ÿฌํ•œ ๋‚ด ๊ถ๊ธˆ์ฆ๋“ค์„ ๋‹ด์•˜๋‹ค.

๊ฐœ์š”

  • Reference Type์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ/์ถ”์ ์„ Reference Count๋ผ๋Š” ์ฐธ์กฐ ์นด์šดํŠธ๋กœ ํ•จ

  • Swift๋Š” ๋Œ€๋ถ€๋ถ„ ARC๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌํ•ด์คŒ

  • ํ•˜์ง€๋งŒ ํŠน์ • ๊ด€๊ณ„์—์„œ compiler์—๊ฒŒ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•จ

  • ARC๋Š” Class instance์— ๋Œ€ํ•ด์„œ๋งŒ ์ ์šฉ๋จ (reference type)

๋™์ž‘ ๋ฐฉ์‹

  • Instance๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค, ARC๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ฒญํฌ(๋ฉ์–ด๋ฆฌ?)๋ฅผ ํ• ๋‹นํ•œ๋‹ค. ์ด๊ฑด ๊ทธ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.
  • ์ด ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ธ์Šคํ„ด์Šค์˜ ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ๋˜ํ•œ ๊ทธ ์ธ์Šคํ„ด์Šค์™€ ๊ด€๋ จ๋œ property๋„ ํ•จ๊ป˜ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ƒฅ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ARC๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ํ• ๋‹นํ•œ๋‹ค๋Š” ์ด์•ผ๊ธฐ
  • ์ถ”๊ฐ€์ ์œผ๋กœ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”์—†๊ฒŒ๋˜๋Š” ARC๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น ํ—ค์ œํ•œ๋‹ค.
  • ๊ฒฐ๊ตญ ARC๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋…€์„
  • ๊ทผ๋ฐ ์ด์ œ ๋ฌธ์ œ๊ฐ€ ๋ญ๋ƒ๋ฉด, ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ํ• ๋‹น ํ•ด์ œํ•˜๋Š” ๊ฒฝ์šฐ์ด๋‹ค.
  • ์ด๋Ÿด ๊ฒฝ์šฐ, ์ด๋ฏธ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ด์ œ๋˜์—ˆ๋Š”๋ฐ, ์ ‘๊ทผํ•˜๊ฒŒ๋˜์–ด ์•ฑ์ด ํฌ๋ž˜์‹œ๋‚œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, ์ฆ‰ ์•„์ง ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ํ• ๋‹นํ•ด์ œํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ARC๋Š” ์–ผ๋งˆ๋‚˜ ๋งŽ์€ properties, constants, ๋ณ€์ˆ˜๋“ค์ด ๊ฐ๊ฐ์˜ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค์— ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ์ถ”์ ํ•œ๋‹ค.
  • ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ํŠน์ • A๋ผ๋Š” ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ์—ฌ๊ธฐ์ €๊ธฐ์„œ ์–ผ๋งˆ๋‚˜ ์ด๋…€์„์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ๊ด€์ฐฐํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ
  • ์ด๋ ‡๊ฒŒ ํ•ด์„œ, ARC๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์ ์–ด๋„ 1๊ฐœ ์ด์ƒ์˜ ์ฐธ์กฐ๋ฅผ ๋ฐ›๊ณ  ์žˆ์„ ๊ฒฝ์šฐ ํ• ๋‹น์„ ํ•ด์ œํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ทธ๋ž˜์„œ ๊ตฌํ˜„ํ•  ๋•Œ, ์ฐธ์กฐ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด strongํ•œ ์ฐธ์กฐ๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.
  • ๊ทธ๋ƒฅ ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ ์ฐธ์กฐํ•˜๋ฉด +1 ํ•˜๋Š”๊ฑฐ์•ผ.

์ฝ”๋“œ๋กœ ์•Œ์•„๋ณด๊ธฐ

class Person {
    let 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?
 

์ด๋ ‡๊ฒŒ ํด๋ž˜์Šค๊ฐ€ ์žˆ๋Š”๋ฐ ์•„๋ž˜์—์„œ optional๋กœ ์„ ์–ธํ–ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—, ์•„์ง ์ธ์Šคํ„ด์Šคํ™” ๋˜์ง€ ์•Š์€ ์ƒํƒœ์ด๋‹ค.

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

์ธ์Šคํ„ด์Šคํ™”๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด์„œ ์ถœ๋ ฅ์„ ํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ธ์Šคํ„ด์Šคํ™” ํ•˜๊ฒŒ๋œ ์ดํ›„์—๋Š” ARC๋Š” ํ•ด๋‹น ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ๋ฅผ ์ถ”์ ํ•˜๊ฒŒ ๋œ๋‹ค. ์ง€๊ธˆ์€ reference1์ด๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— reference count๋Š” 1์ด๊ณ , 1์ด๊ธฐ ๋•Œ๋ฌธ์— ํ• ๋‹นํ•ด์ œ ๋˜์ง€ ์•Š๋Š”๋‹ค.

reference2 = reference1
reference3 = reference1

๊ทธ๋Ÿฌ๋ฉด ์ด๋ ‡๊ฒŒ ๋‘๊ฐœ์˜ ์ถ”๊ฐ€ ๋ณ€์ˆ˜๊ฐ€ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค๋ฉด ์–ด๋–จ๊นŒ? reference count๊ฐ€ 3์ด๋œ๋‹ค.

reference1 = nil
reference2 = nil

์ด๋ ‡๊ฒŒ ๋‘๊ฐœ๋ฅผ ์ฐธ์กฐ ํ•ด์ œํ•˜๊ฒŒ ๋˜๋ฉด reference count๋Š” 1์ด ๋˜๊ฒ ๋‹ค.

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

์ด๋ ‡๊ฒŒ nil๋กœ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋˜๋ฉด, ์ตœ์ข…์ ์œผ๋กœ reference count๋Š” 0์ด๋˜๊ณ , ํ• ๋‹นํ•ด์ œ ๋œ๋‹ค.

๊ฐ•ํ•œ ์ฐธ์กฐ ์ˆœํ™˜

  • ์œ„์—์„œ ๋ณธ ๊ฒƒ์€ ๊ฒฐ๊ตญ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด reference count๊ฐ€ ์–ด๋–ค์‹์œผ๋กœ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์•Œ์•„๋ดค๋‹ค.
  • ๊ต‰์žฅํžˆ ํ•ฉ๋ฆฌ์ ์ด๊ณ  ์ž˜ ๋™์ž‘ํ•  ๊ฒƒ ๊ฐ™์ง€๋งŒ, ํŠน์ • ์ƒํ™ฉ์—์„œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š๋‹ค.
  • strong referece count๊ฐ€ 0์ž„์—๋„ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹นํ•ด์ œ๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ
  • ์ด๋Ÿฐ ์ƒํ™ฉ์€ ๋‘๊ฐœ์˜ class instance๊ฐ€ ์„œ๋กœ๋ฅผ ๊ฐ•ํ•œ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•œ๋‹ค.
  • ์ด๋Ÿฐ ์ƒํ™ฉ์„ strong reference cycle์ด๋ผ ํ•œ๋‹ค.
  • weak ๋˜๋Š” unowned reference๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ด๋Ÿฐ ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
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 }
    var tenant: Person?
    deinit { print("Apartment \(unit) is being deinitialized") }
}
  • ๋ณด๊ฒŒ ๋˜๋ฉด, Person์˜ ํ”„๋กœํผํ‹ฐ์ธ apartment๊ฐ€ ์žˆ๊ณ ,
  • Apartment๋„ Person์„ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

  • ๊ทธ๋ฆผ์œผ๋กœ ๋ณด๋ฉด ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์ด๋‹ค. ๋ณ€์ˆ˜๋“ค์ด ์ƒ์„ฑ๋œ ๊ฐ๊ฐ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค.
  • ์ด์ œ ์—ฌ๊ธฐ์„œ ๊ฐ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ํ”„๋กœํผํ‹ฐ๊ฐ€ ์„œ๋กœ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.
  • ์ด๋ ‡๊ฒŒ ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด, ์ผ๋‹จ john instance์˜ reference count + 1
  • unit4A instance๋„ reference count + 1 ๋˜๊ฒŒ ๋œ๋‹ค.
john!.apartment = unit4A
unit4A!.tenant = john

  • ์กด์žฌํ•˜๋Š” ๊ฒƒ์ด ํ™•์‹คํ•˜๋‹ˆ ๊ฐ•์ œ ์–ธ๋ž˜ํ•‘์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฉด ์œ„์™€ ๊ฐ™์€ ๊ทธ๋ฆผ์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.
  • ๊ฐ๊ฐ์˜ ์ธ์Šคํ„ด์Šค์— ์žˆ๋Š” property๋Š” ์„œ๋กœ๋ฅผ ๊ฐ•ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค.
  • ํ˜„์žฌ Person instance์˜ ์ฐธ์กฐ ๊ฐœ์ˆ˜๋Š” 2๊ฐœ, Apartment instance์˜ ์ฐธ์กฐ ๊ฐœ์ˆ˜ ์—ญ์‹œ 2์ด๋‹ค.
john = nil
unit4A = nil

  • ์ด ์ƒํƒœ์—์„œ john๊ณผ unit4A์˜ ๋ณ€์ˆ˜์˜ ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?
  • ์—ฌ์ „ํžˆ ์ฐธ์กฐ๊ฐœ์ˆ˜๋Š” ๊ฐ๊ฐ 1, 1์œผ๋กœ ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ• ๋‹นํ•ด์ œ ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ด ๋ฌธ์ œ๋Š” ๊ต‰์žฅํžˆ ์‹ฌ๊ฐํ•˜๋‹ค. ์ ‘๊ทผ ์ž์ฒด๋„ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์—, ์˜๋„ํ•œ ๋ฐ”๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๋ ˆ๊ธฐ ๊ฐ’์ด ๊ณ„์†ํ•ด์„œ ๋ˆ„์ ๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•œ๋‹ค.

๊ฐ•ํ•œ ์ฐธ์กฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์Šค์œ„ํ”„ํŠธ๋Š” ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. weak, unowned์ด ๋‘๊ฐ€์ง€์ด๋‹ค.

weak

  • ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์„ ๋•Œ, ๋” ์งง์€ ์ƒ์• ์ฃผ๊ธฐ, ์ฆ‰ ๋” ๋นจ๋ฆฌ ์—†์–ด์งˆ ๊ฒƒ ๊ฐ™์€ ๋†ˆํ•œํ…Œ weak์„ ๋‹จ๋‹ค.
  • ์œ„์˜ ์˜ˆ๋ผ๋ฉด, ์•„ํŒŒํŠธ์˜ ์„ธ์ž…์ž๋Š” ๋” ์ž์ฃผ๋ฐ”๋€๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์„ธ์ž…์ž์•ž์— weak ๋‹ค๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ํ•ต์‹ฌ์€ ์ฐธ์กฐํ•˜๋˜ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ•ํ•œ ์ฐธ์กฐ count๊ฐ€ 0์ด ๋œ ๊ฒฝ์šฐ, ARC๋Š” ์ด๋ฅผ ํ• ๋‹น ํ•ด์ œํ•ด๋ฒ„๋ฆฐ๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฉด weak ํ‚ค์›Œ๋“œ๋ฅผ ๋‹ฌ๊ณ  ์ฐธ์กฐ๋ฅผ ํ•˜๊ณ  ์žˆ๋˜ ๋…€์„์€ โ€œ์‘? ๋‚œ ๊ณ„์† ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ค‘์ž„ ใ…‡ใ…‡โ€ ์ด๋Ÿฐ์‹์œผ๋กœ ์–ผ์„ ํƒ€๊ฒŒ ๋œ๋‹ค.
  • ์ฆ‰ ์“ฐ๋ ˆ๊ธฐ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค.
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ARC๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ด์ œ๋˜์—ˆ์„ ๋•Œ, weak ์ฐธ์กฐ๋ฅผ ํ•œ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด nil์„ ์ค˜๋ฒ„๋ฆฐ๋‹ค.
  • ์ด๋Ÿฌํ•œ ๊ฒƒ์€ ๋Ÿฐํƒ€์ž„์—์„œ ๋ฒŒ์–ด์ง„๋‹คโ€ฆ!!!!
  • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— weak์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฌด์กฐ๊ฑด var ๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ํ• ๋‹น์ด ํ•ด์ œ๋  ๋•Œ optional์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์กฐ๊ฑด optional๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.
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์œผ๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ์œ„์™€ ๊ฐ™์ด ์„ ์–ธ์„ ํ•ด์ค€ ์ƒํƒœ์ด๋‹ค. ์ด์ œ ์ด์ƒํ™ฉ์—์„œ john์˜ ์ฐธ์กฐ๋ฅผ ๋Š์–ด๋ณด์ž.

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

tenant๋Š” weak ์ฐธ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— Person instance์˜ reference count๋Š” 0์ด ๋˜์–ด ํ• ๋‹น์ด ํ•ด์ œ ๋œ๋‹ค. ARC๋Š” weak์œผ๋กœ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋˜ tenant ๋ณ€์ˆ˜์˜ ๊ฐ’์„ nil๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

์ด์ œ ์ด ์ƒํ™ฉ์—์„œ unit4A๋„ ํ• ๋‹น์„ ํ•ด์ œํ•ด๋ณด์ž.

unit4A = nil
// Prints "Apartment 4A is being deinitialized"

์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ๋‹ค! Apartment instance๋„ reference count๊ฐ€ 1์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, unit4A๊ฐ€ ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋Š” ์ˆœ๊ฐ„ 0์ด๋˜์–ด ํ• ๋‹น์ด ํ•ด์ œ๋˜์—ˆ๋‹ค.

unowned

  • unowned์—ญ์‹œ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.
  • ๊ทธ๋Ÿฐ๋ฐ, ์ด๊ฑด ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ฐ™๊ฑฐ๋‚˜ ๊ฑฐ ๊ธด ์ƒ์• ์ฃผ๊ธฐ๋ฅผ ๊ฐ€์งˆ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • weak ์ฐธ์กฐ์™€ ๋‹ค๋ฅด๊ฒŒ, ์ด๋…€์„์€ ํ•ญ์ƒ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•œ๋‹ค.
  • ์ฆ‰, unowned๋กœ ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด, ARC๋Š” value๋ฅผ nil๋กœ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๊ทธ๋ž˜์„œ ์ด ์ฐธ์กฐ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ญ์ƒ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•  ๋•Œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ๋งŒ์•ฝ์— unowned ๋กœ ์„ ์–ธ๋œ ๊ฐ’์ด ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ด์ œ๋œ ์ดํ›„ ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.
class Customer {
    let name: String
    var card: CreditCard?
    init(name: String){
        self.name = name
    }
    deinit { print("\(name) is being deinitialized") }
}
 
class CreditCard {
    let number: UInt64
    unowned let customer: Customer
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card #\(number) is being deinitialized") }
}
  • Person class์™€ ์‹ ์šฉ์นด๋“œ ํด๋ž˜์Šค์ด๋‹ค.
  • ์„œ๋กœ๋Š” ์„œ๋กœ์˜ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ํ”„๋กœํ„ฐํ”ผ๋กœ์„œ ์ €์žฅํ•œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์€ ๊ฐ•ํ•œ ์ฐธ์กฐ ์ˆœํ™˜ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์ด๋‹ค.
  • ์—ฌ๊ธฐ์„œ ๊ฐ์ฒด๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์ž˜ ์‚ดํŽด๋ณด์•„์•ผ ํ•œ๋‹ค.
  • ์ด์ „์— ์•„ํŒŒํŠธ์™€ ์„ธ์ž…์ž์˜ ๊ฒฝ์šฐ ์„ธ์ž…์ž๊ฐ€ ์—†์–ด๋„ ์•„ํŒŒํŠธ๋Š” ์˜๋ฏธ๋ก ์ ์œผ๋กœ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•˜์ง€๋งŒ ์ง€๊ธˆ ๊ณ ๊ฐ๊ณผ ์‹ ์šฉ์นด๋“œ์—์„œ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค.
  • ๊ณ ๊ฐ์€ ์‹ ์šฉ์นด๋“œ๊ฐ€ ์žˆ์–ด๋„ ๊ทธ๋งŒ, ์—†์–ด๋„ ๊ทธ๋งŒ์ด์ง€๋งŒ
  • ์‹ ์šฉ์นด๋“œ๋Š” ์ด ์ฃผ์ธ์ด ๋ช…ํ™•ํ•ด์•ผ ์‚ฌ์šฉ๊ฐ€์น˜๋ฅผ ๊ฐ–๋Š”๋‹ค.
  • ์ด๋Ÿฌํ•œ ์ ์€ ๋ฐ˜์˜ํ•œ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    • ์‹ ์šฉ์นด๋“œ ์ดˆ๊ธฐํ™”์‹œ ๊ณ ๊ฐ ๋ฌด์กฐ๊ฑด ์žˆ์–ด์•ผ ํ•จ
    • ๊ณ ๊ฐ์„ ์˜ต์…”๋„ ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•˜์ง€ ์•Š์Œ
    • ๋ฐ˜๋Œ€๋กœ ๊ณ ๊ฐ ํด๋ž˜์Šค์—์„œ๋Š” ์นด๋“œ๋ฅผ ์˜ต์…”๋„๋กœ ์„ ์–ธํ•จ
    • ๊ณ ๊ฐ์ด ๊ฐ‘์ด๋ฏ€๋กœ ์นด๋“œ๋ฅผ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ํ•˜๊ณ  ์žˆ์Œ

์ž ์ด์ œ, ์‹ค์ œ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฑด ๊ทธ๋ฆผ์„ ๋ณด๋ฉด์„œ ์ดํ•ดํ•˜์ž.

var john: Customer?
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
  • ์ž ์ด๋ ‡๊ฒŒ ์„ ์–ธํ•ด๋ณด์ž.
  • ์ผ๋‹จ ๊ณ ๊ฐ์„ ํ•˜๋‚˜ ๋งŒ๋“ค์—ˆ๊ณ , ๊ทธ ๊ณ ๊ฐ์ด ์‚ฌ์šฉํ•œ ์‹ ์šฉ์นด๋“œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฐธ์กฐํ–ˆ๋‹ค.

๊ทธ๋ฆผ์œผ๋กœ ๋ณด๋ฉด ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์ด๋‹ค. ์ด ์ƒํƒœ์—์„œ john์˜ ์ฐธ์กฐ๋ฅผ ํ•ด์žฌํ•ด ๋ณด์ž.

๊ทธ๋Ÿฌ๋ฉด ์ด๋Ÿฌํ•œ ์ƒํƒœ๊ฐ€ ๋  ํ…๋ฐ, unowned๋กœ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ณ ๊ฐ ์ธ์Šคํ„ด์Šค๋Š” ํ• ๋‹น ํ•ด์ œ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ, ๊ทธ๋Ÿฌ๋ฉด ์‹ ์šฉ์นด๋“œ ์ธ์Šคํ„ด์Šค๋„ ๊ฐ•ํ•œ ์ฐธ์กฐ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ• ๋‹น ํ•ด์ œ๋œ๋‹ค.

john = nil
// Prints "John Appleseed is being deinitialized"
// Prints "Card #1234567890123456 is being deinitialized"

์ •๋ฆฌ

  • weak: ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ nil์ด ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์„ ๋•Œ
  • unowned: ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ nil์ด ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์—†์„ ๋•Œ

Garbage Collector, Reference Counting ๋น„๊ต

|๊ตฌ๋ถ„|GC|RC| |::----|::|::| |์ฐธ์กฐ ๊ณ„์‚ฐ ์‹œ์ |Run Time
์–ดํ”Œ ์‹คํ–‰ ๋™์•ˆ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ฐธ์กฐ๋ฅผ ์ถ”์ ํ•˜์—ฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” instance๋ฅผ ํ•ด์ œํ•จ|Compile Time
์ปดํŒŒ์ผ ์‹œ์ ์— ์–ธ์ œ ์ฐธ์กฐ๋˜๊ณ  ํ•ด์ œ๋˜๋Š”์ง€ ๊ฒฐ์ •๋˜์–ด ๋Ÿฐํƒ€์ž„ ๋•Œ ๊ทธ๋Œ€๋กœ ์‹คํ–‰๋จ| |์žฅ์ |์ธ์Šคํ„ด์Šค๊ฐ€ ํ•ด์ œ๋  ํ™•๋ฅ ์ด ๋†’์Œ
(RC์— ๋น„ํ•ด)|๊ฐœ๋ฐœ์ž๊ฐ€ ์ฐธ์กฐ ํ•ด์ œ ์‹œ์ ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Œ
RunTime ์‹œ์ ์— ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ| |๋‹จ์ |๊ฐœ๋ฐœ์ž๊ฐ€ ์ฐธ์กฐ ํ•ด์ œ ์‹œ์ ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์—†์Œ
RunTime ์‹œ์ ์— ๊ณ„์† ์ถ”์ ํ•˜๋Š” ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค๊ฐ€ ํ•„์š”ํ•˜์—ฌ ์„ฑ๋Šฅ์ €ํ•˜ ๋ฐœ์ƒ๋  ์ˆ˜ ์žˆ์Œ|์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒ ์‹œ ์˜๊ตฌ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ|

Reference