Swift: Strong, Weak, Unowned

Snack 남관식·2023년 8월 14일
0

Swift

목록 보기
7/7
post-thumbnail

Strong, Weak, Unowned

  • Swift의 메모리 관리 시스템에서 참조의 유형을 정의할 때 사용되는 키워드

순환 참조

  • A가 B를 참조하고 B가 A를 참조하는 경우 같이 두 객체가 서로를 참조하면 순환 참조가 발생한다.
  • 순환 참조가 발생하면 ARC의 Reference Count가 절대 0이 되지 않아 메모리에서 해제되지 않고 메모리 누수(Memory Leak)가 발생한다.
class ClassA {
    var instanceB: ClassB?
    deinit {
        print("ClassA Deinitialized")
    }
}

class ClassB {
    var instanceA: ClassA?
    deinit {
        print("ClassB Deinitialized")
    }
}

var instanceA: ClassA? = ClassA()
var instanceB: ClassB? = ClassB()

// 서로의 인스턴스 참조
instanceA?.instanceB = instanceB
instanceB?.instanceA = instanceA

// nil이 되었지만 참조가 해제되지 않아 순환 참조 발생
instanceA = nil
instanceB = nil

Strong(강한 참조)

  • 기본적인 참조 유형으로 별도의 지정자를 사용하지 않으면 strong 참조이다.
  • Reference Count를 1 증가시켜, 객체를 참조하고 있으면 해당 객체는 메모리에서 해제되지 않는다.
class Person {
    var pet: Pet?
}

class Pet {
    var owner: Person?
}

let snack = Person()
let cream = Pet()

snack.pet = cream
cream.owner = snack

// 순환 참조가 발생하여 snack과 cream 객체는 메모리에서 해제되지 않는다.

Weak(약한 참조)

  • 객체의 Reference Count를 증가시키지 않는다.
  • weak 참조를 통해 참조되는 객체가 없어지면 자동으로 nil이 되기 때문에, weak 참조는 항상 옵셔널 타입이어야 한다.
class Person {
    var pet: Pet?
}

class Pet {
    weak var owner: Person?
}

let snack = Person()
let cream = Pet()

snack.pet = cream
cream.owner = snack

// cream 객체가 메모리에서 해제되면 cream.owner는 자동으로 nil이 된다.

Unowned(미소유 참조)

  • 객체의 Reference Count를 증가시키지 않는다.
  • unowned 참조는 참조하는 대상이 항상 메모리에 존재할 것이라는 확신이 있을 때 사용하기 때문에 옵셔널 타입이 될 수 없다.
  • 참조되는 객체가 메모리에서 해제되어도 해당 참조를 계속 하려하기 때문에 런타임 오류가 발생한다.
class Person {
    var pet: Pet?
}

class Pet {
    unowned var owner: Person
    init(owner: Person) {
        self.owner = owner
    }
}

let snack = Person()
let cream = Pet(owner: snack)

snack.pet = cream

// snack 객체가 메모리에서 해제되고 이후에 cream.owner에 접근하려고 시도하면 런타임 오류가 발생한다.

profile
iOS Developer | Product Designer @snacknam

0개의 댓글