SwiftFrequency / iOSInterview

 iOS 개발자로 취업할 때 알아야 할 모든 것
20 stars 1 forks source link

순환 참조에 대하여 설명하시오. #10

Open heerucan opened 3 years ago

dlwns33 commented 3 years ago
class Man {
    var name: String
    var girlfriend: Woman?

    init(name: String) {
        self.name = name
    }
    deinit { print("Man Deinit!") }
}

class Woman {
    var name: String
    var boyfriend: Man?

    init(name: String) {
        self.name = name
    }
    deinit { print("Woman Deinit!") }
}

Man, Woman 클래스가 있다.

Man에게는 Woman타입의 프로퍼티(girlfriend)가 있고,

Woman에게는 Man 타입의 프로퍼티(boyfriend)가 있다.

있을수도 있고 없을 수도 있으니 옵셔널 타입이다.

var chelosu: Man? = .init(name: "철수")
var yeonghee: Woman? = .init(name: "영희")

Man, Woman RC +1

근데 만약에...

chelosu?.girlfriend = yeonghee
yeonghee?.boyfriend = chelosu

어떡하냐...

Man, Woman 다시 +1

boyFriend 프로퍼티엔 Man 인스턴스의 주소값을 할당하고,

girlFriend 프로퍼티엔 Woman 인스턴스의 주소값을 할당함

또한 girlFriend, boyFriend 프로퍼티는 기본 값 strong이기 때문에

서로의 RC 값이 1씩 증가해버린 것임

철수 인스턴스의 프로퍼티는 영희를 참조하고,

영희 인스턴스의 프로퍼티는 철수를 참조하는 것 처럼

두 개의 객체가 서로가 서로를 참조하고 있는 형태를 순환 참조 라고 한다.

heerucan commented 3 years ago
class ClassA {
    var objB: ClassB!
    deinit { print("A 객체 해제") }
}

class ClassB {
    var objA: ClassA!
    deinit { print("B 객체 해제") }
}
var a: ClassA! = ClassA()    // -> A 객체 R.C = 1
var b: ClassB! = ClassB()    // -> B 객체 R.C = 1

여기서 ClassA의 인스턴스인 a가 ClassA 객체를 참조하고 있기 때문에 A객체의 R.C가 1 증가하고 ClassB의 인스턴스인 b가 ClassB 객체를 참조하고 있어서 B객체의 R.C가 1 증가합니다.

a = nil    // -> A 객체 R.C = 0
b = nil    // -> B 객체 R.C = 0

그런데 프로퍼티 a와 b에 각각 nil을 대입 소유권을 해제 즉, 객체를 해제시켜줬기 때문에 ClassA와 ClassB 객체의 R.C가 0이 됩니다.

이를 순환 참조라고 합니다.

Taehyeon-Kim commented 3 years ago

두 개의 객체가 서로를 참조하고 있는 형태를 순환 참조라고 한다. 순환 참조가 발생하면 메모리가 영구적으로 해제되지 않는 이슈가 발생할 수도 있다.