본문 바로가기

스폰지밥으로 공부하는 swift/swift 문법

unowned vs weak 뭐가 다른데?

728x90

미소유 참조(unowned)와 약한 참조(weak)

저번 포스팅에서 참조에 대해서 잠깐 다뤘던 내용이지만 미소유 참조(unowned)와 약한 참조(weak)는 둘 다 참조 카운트를 증가시키지 않아요. 이 두 가지는 순환 참조 문제를 해결하기 위해 사용되는데요, 사용 방식과 특징에 약간의 차이가 있습니다.

 

1. 미소유 참조(unowned): 미소유 참조는 참조하는 객체가 항상 메모리에 존재할 것이라는 전제 하에 사용됩니다. 따라서 미소유 참조를 통해 객체에 접근할 때 nil 검사를 하지 않아도 됩니다. 하지만 참조하는 객체가 메모리에서 해제된 후에 미소유 참조를 통해 접근하려고 하면 런타임 오류가 발생합니다.

 

2. 약한 참조(weak): 약한 참조는 참조하는 객체가 메모리에서 언제든지 해제될 수 있다는 전제 하에 사용됩니다. 따라서 약한 참조를 통해 객체에 접근할 때는 항상 nil 검사를 해야 합니다. 참조하는 객체가 메모리에서 해제된 후에 약한 참조를 통해 접근하려고 하면 nil을 반환하므로, 런타임 오류는 발생하지 않습니다.

 

🤓 스펀지밥과 징징이를 또 데려와 볼게요!

class SpongeBob {
    var name = "스펀지밥"
    var friend: Squidward?  // 징징이를 참조하는 변수
}

class Squidward {
    var name = "징징이"
    unowned var friend: SpongeBob  // 스펀지밥을 미소유 참조하는 변수
}

var spongeBob: SpongeBob? = SpongeBob()
var squidward: Squidward? = Squidward()

spongeBob?.friend = squidward  // 스펀지밥은 징징이를 참조합니다.
squidward?.friend = spongeBob!  // 징징이는 스펀지밥을 미소유 참조합니다.

spongeBob = nil  // 스펀지밥이 메모리에서 해제됩니다.
print(squidward?.friend.name)  // 런타임 오류가 발생합니다.

위 코드에서 unowned var friend: SpongeBob는 Squidward 인스턴스가 SpongeBob 인스턴스를 미소유 참조하도록 선언한 부분입니다.

해당 코드를 실행하면 스펀지밥이 메모리에서 해제된 후에 징징이가 스펀지밥을 참조하려고 하므로 런타임 오류가 발생합니다.

이런 상황에서 안전하게 코드를 작성하려면 약한 참조를 사용해야 합니다.

class SpongeBob {
    var name = "스펀지밥"
    var friend: Squidward?  // 징징이를 참조하는 변수
}

class Squidward {
    var name = "징징이"
    weak var friend: SpongeBob?  // 스펀지밥을 약한 참조하는 변수
}

var spongeBob: SpongeBob? = SpongeBob()
var squidward: Squidward? = Squidward()

spongeBob?.friend = squidward  // 스펀지밥은 징징이를 참조합니다.
squidward?.friend = spongeBob  // 징징이는 스펀지밥을 약한 참조합니다.

spongeBob = nil  // 스펀지밥이 메모리에서 해제됩니다.
print(squidward?.friend?.name)  // nil을 출력합니다.

weak var friend: SpongeBob?은 Squidward 인스턴스가 SpongeBob 인스턴스를 약한 참조하도록 선언 되어 있습니다. 이 코드를 실행하면 스펀지밥이 메모리에서 해제된 후에 징징이가 스펀지밥을 참조하려고 해도 nil을 반환하므로, 런타임 오류가 발생하지 않습니다.

이렇게 미소유 참조는 참조하는 객체가 항상 메모리에 존재할 것이라는 확신이 있을 때 사용하고, 약한 참조는 참조하는 객체가 언제든지 메모리에서 해제될 수 있음을 인지하고 사용해야 합니다.

다음 포스팅에서는 클로저와 캡처리스트에 대해 다루겠습니다 😆