순환참조 문제
변수나 상수가 참조타입의 인스턴스를 참조할 경우 따로 키워드를 지정하지 않으면 strong 즉 강한 참조를 하게 되는데, 참조타입을 증가시키는 것도 모두 이 강한참조일 때만 발생한다.
이때, 두 클래스가 서로를 참조하는 프로퍼티를 모두 갖는다면, 힙에서 두 인스턴스 모두 영원히 해제되지 않는 상황이 발생한다.
- A의 프로퍼티가 B 강한참조, B의 프로퍼티가 A 강한참조→ B RC: 2 (생성될때, A에의해 참조될때)
- → A RC: 2 (생성될때, B에의해 참조될때)
- A = nil, B = nil→ B RC: 1 (nil로 인한 -1, A가 메모리 상에 있으므로 A에 의해 증가한 참조횟수 1이 그대로 남아있음)
- → A RC: 1 (nil로 인한 -1, 그치만 B에의해 증가된 참조횟수 1이 남아있어서 메모리에서 해제되지 않음)
- 둘다 메모리에 남게 됨 = 순환참조 문제!
이를 방지하기 위해 참조해도 참조횟수를 증가시키지 않는 weak와 unowned 키워드를 사용
강한참조 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 도구를 이용하여 체크.
참고자료
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
'iOS' 카테고리의 다른 글
[iOS+@] Concurrency (동시성) (0) | 2025.03.25 |
---|---|
[iOS+@] Dependency Injection (의존성 주입) (0) | 2025.03.24 |
[iOS] Combine 기초 (추가 중) (0) | 2025.02.13 |
[SwiftUI] Environment value : dismiss (NavigationStack에서 뷰 닫기) (0) | 2024.12.26 |
[또러블슈팅] CloudKit + CoreData 을 사용하는 App에서 iCloud 동기화가 안되는 문제 (0) | 2024.12.12 |