본문 바로가기
iOS

[Swift] 순환참조와 strong, weak, unowned

by SiO2whocode 2025. 3. 14.

 

순환참조 문제

변수나 상수가 참조타입의 인스턴스를 참조할 경우 따로 키워드를 지정하지 않으면 strong 즉 강한 참조를 하게 되는데, 참조타입을 증가시키는 것도 모두 이 강한참조일 때만 발생한다.

이때, 두 클래스가 서로를 참조하는 프로퍼티를 모두 갖는다면, 힙에서 두 인스턴스 모두 영원히 해제되지 않는 상황이 발생한다.

  1. A의 프로퍼티가 B 강한참조, B의 프로퍼티가 A 강한참조→ B RC: 2 (생성될때, A에의해 참조될때)
  2. → A RC: 2 (생성될때, B에의해 참조될때)
  3. A = nil, B = nil→ B RC: 1 (nil로 인한 -1, A가 메모리 상에 있으므로 A에 의해 증가한 참조횟수 1이 그대로 남아있음)
  4. → A RC: 1 (nil로 인한 -1, 그치만 B에의해 증가된 참조횟수 1이 남아있어서 메모리에서 해제되지 않음)
  5. 둘다 메모리에 남게 됨 = 순환참조 문제!

이를 방지하기 위해 참조해도 참조횟수를 증가시키지 않는 weakunowned 키워드를 사용


강한참조 strong

참조하는 인스턴스의 참조횟수를 1 증가시킴. 따로 선언하지 않아도 default가 strong 이다.

 

약한참조 weak (권장)

참조횟수 증가 X, nil이 될 수 있음, 옵셔널 변수 (참조하는 인스턴스가 메모리에서 해제될 경우를 염두)

!! 인스턴스의 프로퍼티로 다른 인스턴스를 참조할 때 본인보다 수명이 짧은 인스턴스를 weak로 참조해야 메모리를 더 효율적으로 관리할 수 있음

 

미소유참조 unowned

참조횟수 증가 X, nil이 되지 않는다고 가정, 옵셔널 X (swift 5 부터는 옵셔널 지정 가능)

인스턴스가 메모리에 없을 경우 런타임 오류

!! nil일 수 없다고 가정하기 때문에, 해당 인스턴스 보다 수명이 더 긴 인스턴스를 참조할 때 사용하길 권장한다. (weak랑 반대)

만약 참조하는 인스턴스가 메모리에서 해제되면 strong 처럼 nil이 자동으로 할당되는게 아니라 그 주소 값을 그대로 갖고 있음. (참조하던 인스턴스가 해제된 후 그 변수에 다시 접근하려고 하면 런타임에러 발생)


Q. 객체간 순환참조를 발견하는 방법?

  • deinit 을 오버라이드해서 로깅 코드를 써두고, 객체가 해제되는지 확인하기
  • Xcode Memory Graph 이용해서 Live Object 들을 확인하고, Leak 된 Object 를 체크.
  • Instrument 의 Leak 도구를 이용하여 체크.

 

 

 


참고자료

https://medium.com/@sylpid003/swift-xcode-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B7%B8%EB%9E%98%ED%94%84-%EB%B6%84%EC%84%9D-tca-project-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%88%84%EC%88%98-%ED%95%B4%EA%B2%B0-c11580e1b30b

 

Swift: Xcode 메모리 그래프 분석 & TCA Project 메모리 누수 해결

instruments, terminal 로 메모리 누수를 분석하고 문제를 해결해 보자.

medium.com

https://babbab2.tistory.com/27

 

iOS) 메모리 관리 (2/3) - strong , weak, unowned, 순환 참조

안녕하세여 소들입니다! 저번 포스팅이 길어져서 한번 끊고 가봅니다 :) 뭐 흐름 상 끊어도 될만한 부분이었어서.. ~_~ 이번에 공부할 내용은 뭐 제목에서 써놓은 것처럼 strong weak unowned 순환 참조

babbab2.tistory.com

 

728x90