💽 메모리 참조 (weak, strong, unowned)

2022. 6. 24. 16:49카테고리 없음

 

 

 

weak var는 무슨 뜻일까? 

 

 

 


 

Strong

객체를 참조하고 reference count를 증가

var ref: Person? = Person(name: "Colli") // 강한 참조
ref = nil // 메모리 해제 과정

- 강한 참조를 하게 되면 reference count가 증가함

-> 해당 객체에 nil을 넣어야 메모리가 해제 !

 

 

 

 

 

강한 순환 참조(Strong Reference Cycles)

: 두 개의 객체가 상호 참조하는 경우, 강한 순환 참조 발생 가능

-> reference count가 0이 되지 못해, 메모리 누수 발생

-> 뭔가 객프 시간에 cpp하면서 배웠던 거랑 유사하다. 메모리 누수!

 

 

 

//자기 자신의 객체를 가지는 클래스
class Strong {
    var strong: Strong? = nil // Strong
}

var strong1: Strong? = Strong()  
var strong2: Strong? = Strong() 

// 강한 순환 참조
strong1?.strong = strong2
strong2?.strong = strong1

//두 객체 변수 메모리 해제
strong1 = nil
strong2 = nil

 

 

 

두 개의 객체 변수는 마지막에 nil을 넣어 메모리 해제 O

: 각각의 객체는 강한 참조가 되었기 때문에 메모리 해제 X

객체인 strong은 nil을 넣어주지 못하고, 객체 변수의 메모리를 해제

-> 객체에 접근할 방법도 없고 메모리를 해제할 방법도 없어 메모리 누수 발생!

 

 

 

 

 

+

 

 

Strong Reference Cycle은 memory leak 의 원인

1. A가 B를 참조한다.
2. B가 A를 참조한다. (무한 거울)
3. A가 메모리에서 해제되려고 한다.
4. 그런데 B가 참조하고 있다. +> A도 B를 참조하고 있다.
5. iOS는 현재 두 객체는 메모리에서 해제하면 안된다고 판단
-> 그렇게 둘은 앱이 종료될 때까지 유지

 

 

B가 A를 참조하긴 하는데, 약한 참조로 A가 사라지면 참조 해제해!

-> 그래서 사용하는 개념이 “weak” 입니다.

 

 

 

 

강한 순환 참조(Strong Reference Cycle)를 해결하는 방법 2 개

1) 약한 참조(weak reference)

2) 미소유 참조(unowned reference)

 

 

 


 

Weak

객체를 참조하고, reference count는 변화 X

weak var ref: Person? = Person(name: "Colli") 
// 앞에 weak를 붙여 약한 참조 !
// 약한 참조 -> 바로 객체가 해제되어 nil

 

 

 

약한 참조는 강한 순환 참조를 해결하기 위해 사용되는 가장 보편적인 방법

주로 인스턴스의 생명주기가 짧을 때 사용한다.

참조하고 있는 인스턴스를 강하게 유지하지 않기 때문에, 약한 참조로 참조하고 있는 동안 인스턴스 메모리 해제 가능

 

 

 

class Strong {
    weak var strong: Strong? = nil 
}

var strong1: Strong? = Strong()  
var strong2: Strong? = Strong() 

// 강한 순환 참조
strong1?.strong = strong2
strong2?.strong = strong1

//두 개의 객체 변수 메모리 해제
strong1 = nil
strong2 = nil

 

 

클래스의 객체 부분을 약한 참조로 정의함!

: 약한 참조를 하기 위해서는 변수의 앞에 weak를 붙이면 된다. 

- 메모리가 해제 시 강한 참조와 달리 약한 참조를 한 객체는 ARC에서 자동으로 객체의 메모리까지 해제 

-> 메모리 누수 문제 해결 가능 ! 

 


 

Unowned

미소유 참조: 객체를 참조하고, reference count는 변화 없음

 

 

약한 참조와 마찬가지로 인스턴스가 참조하는 것을 강하게 유지하지 

BUT 약한 참조와는 달리 다른 인스턴스와 같은 생명주기를 가지거나 더 긴 생명주기를 가질 때 사용

가장 큰 차이점인 부분: 미소유 참조는 Optional에 사용 X

-> 따라서 nil값을 가질 수 없고 항상 값을 가지고 있어야 함

 

참조하는 객체의 참조계수가 0이 되어 메모리가 해제되는 경우

약한 참조에서는 참조 값이 nil로 대체되지만 미소유 참조에서는 참조 값 그대로 유지

 

 

  • strong : reference count를 증가시켜 ARC로 인한 메모리 해제를 피하고, 객체를 안전하게 사용하고자 할 때 사용.
  • weak : 순환 참조에 의해 메모리 누수 문제를 막기 위해 사용.
  • unowned : 객체의 life cycle이 명확하고 개발자에 의해 제어 가능이 명확한 경우, weak Optional 타입 대신하여 사용.

 

 


 

 

출처:

 

https://velog.io/@wook4506/iOS-Swift-메모리-참조-방법-strong-weak-unowned

https://velog.io/@kipsong/Swift-weak-unowned