본문 바로가기

Swift(IOS)

[내용정리] Swift - 메모리 관리 Weak, Strong, Unowned?

Swift로 ios를 개발하면서 메모리 관리를 어떻게 해야지? 라는 생각을 한번쯤은 해봤을것이다.

Swift는 ARC를 지원해주는 언어이다.

 

 

ARC란 무엇일까? 

Automatic Reference Counting의 약자로써

컴파일시에 코드를 분석하여 자동적으로 retain(유지), release(풀기) 코드를 생성해준다.

중요한것은 말그대로 횟수를 추적하여

더이상 참조되지 않는 인스턴스는 메모리에서  헤제해준다.

반대로 얘기하면 메모리를 자동으로 올려주기도하여 해당 메모리를 풀어주지 않을경우 메모리 누수가 발생한다.

 

 

strong(강한참조)

  • 해당 인스턴스의 소유권을 가진다.
  • 자신이 참조하는 인스턴스의 retain count가 증가된다.
  • 값 지정시에 ratain이 되고 참조가 종료될때 release가 된다.
  • 프로퍼티 선언시에 아무것도 적지 않을시에 기본값으로 strong이 할당된다. 
var instenseSample = Instance() // 객체 생성시 retain count가 1 증가하게됨
instenseSample = nil // nil을 할당하게되어 retain count가 1감소 -> 0이되어 메모리 헤제됨

 

 

weak(약한참조)

  • 해당 인스턴스의 소유권을 갖지 않고 주소값만 가지고 있는다.(흡사 포인터)
  • 참조하고 있는 인스턴스의 retain count를 증가시키지 않고 realease도 발생시키  않는다.
  • 본인이 참조는 하고있지만 weak메모리를 헤제시킬수 있는 권한은 타클래스가 갖고있다.
  • 메모리 헤제시에 자동적으로 reference가 nil로 초기화 해준다.
  • weak 참조를 사용하는 객체는 항상 optional타입 이어야한다. (nil일수도 있어서)
    optional에 대해서 정리한 글
    https://yoonds-develop.tistory.com/28
weak var instenseSample = Instance() // 객체가 weak으로 생성되어, 바로 해제되어 nil이 된다.

 

 

unowned(미소유 참조) (필자는 unknowned으로 잘못읽어서 알려지지 않는으로 잘못봄)

  • 해당 인스턴스의 소유권을 갖지 않는다. (weak과 다르게 주소값을 갖고있지는 않다)
  • 참조하고 있는 인스턴스의 retain count를 증가시키지지 않는다.
  • nil이 할당될수 없다. (optional로 선언되면 안된다)
unowned var instanceSam = Instance() // 객체생성과 동시에 댕글링 포인트를 소유

 

 

weak과 unownded는 비슷한 부분이 참 많은것 같다. 둘의 차이는 무엇일까?

  • weak는 객체를 지속적으로 추적하여 객체가 사라질시에 nil로 변환시킨다.
  • unowned는 객체가 사라질시에 댕글링 포인터(nil이 아님)가 남는다.
    (unowned의 댕글링 포인터를 참조하게되면 crash발생하므로 사라지지 않을것이라고 보장되는 객체에만 할당해야한다.)

    * 댕글링 포인터: 원래 할당되어있던 객체가 헤제되었지만 헤제된 메모리 주소를 계속 갖고 있는 것
    (쉽게 얘기하여 집을 지어서 잘갖고 있다가 집을 허물어 부숴서 없어젔지만 존재하지도 않는 그집주소를 계속 바라보고 있음)

 

 

댕글링 포인터를 참조할수 있는 위험성 때문에 weak만 사용하게되면 어떨까?

안전하게 사용하고 싶다면 weak만 사용하여 코드를 작성할 수 있다.

하지만 unowned를 사용하는 이유는  weak를 사용하게되면 객체를 추적하는 것도

런타임시 오버헤드라고 생각되어 unowned를 사용하게 되는 것이다.

 

* 오버헤드: 개발측면에서의 오버헤드란 추가적으로 시간, 메모리, 자원이 사용되는 현상을 말한다.

(10초면 끝날 작업을 오버헤드로 인해 30초가 걸리게 되면 20초의 오버헤드가 발생된것)

 

 

각 어떤상황에서 쓰여질까?

  • strong: Reference Count를 증가시켜 ARC메모리 헤제를 피하며, 객체를 안전하게 사용할 때
    (강하게 할당하여 메모리에 올려놓고 따로 nil을 넣어줘야 헤제됨)
  • weak: retain cyle에 메모리가 누수되는 문제를 막기위해 사용, weak키워드 선언이후 
    (delegate패턴이 이에 해당됨)
  • unowned: 객체의 라이프 사이클이 명확하며 개발자에 의해 제어 가능이 명확한경우
    (개발자가 확실히 제어해줄거라는 보장이 될 때)

 

 

Reference Address

https://shark-sea.kr/entry/iOS-ARC-strong-weak-unowned  

 

https://devsrkim.tistory.com/entry/Swift-%EB%A9%94%EB%AA%A8%EB%A6%AC%EB%A5%BC-%EC%B0%B8%EC%A1%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-Strong-Weak-Unowne

 

https://donggu1105.tistory.com/175