iOS
iOS) 강한 순환 참조(Strong Reference Cycle)는 어떤 경우에 발생하나요?
hyun99999
2023. 7. 12. 18:29
728x90
반응형
"인스턴스가 계속 사용되야 하기 때문에 메모리에 남아있어야 한다." 라는 명분을 주는 것이 Strong Reference(강한 참조)입니다.
레퍼런스 카운트가 증가될 때는 강한 참조인 경우에 해당합니다. 이 강한 참조는 별도의 식별자를 명시하지 않으면 강한 참조로 여겨집니다.
이때 어떤 상황에 대해서 클래스의 인스턴스의 사용이 끝났음에도 불구하고 레퍼런스 카운트가 0이 되지 않아 메모리에서 사라지지 않는 memory leak 이 발생하는 것을 강한참조 순환(strong reference cycle)이다.
언제 발생하나요?
- 두 개 이상의 인스턴스가 서로를 강하게 참조하여 발생하게 된다.
- 변수에 인스턴스를 할당하며 생기는 레퍼런스 카운트 이외에 서로가 참조하면서 레퍼런스 카운트가 추가로 증가. nil 을 할당하더라도 레퍼런스 카운트가 0이 되지 않게 된다.
- 또한, view controller 와 collection view cell 버튼 액션과 같은 관계에서 delegate 를 사용하여 view controller 에 동작을 지정하는 것과 같을 때도 발생
class Cell: UICollectionViewCell {
// ✅ 강한 참조가 발생하기 때문에 weak var 을 사용해야 함.
var delegate: Delegate?
// ...
button.addTarget(self, action: #selector(touchAction), for: .touchUpInside)
@objc func touchAction() {
delegate.touch()
}
}
class ViewController: UIViewController, TestDelegate {
var cell: Cell?
override func viewDidLoad() {
super.viewDidLoad()
// ...
cell?.delegate = self
}
func touch() {
// Cell 의 버튼 액션으로 view controller 에서 작업할 task 지정.
}
}
protocol Delegate: AnyObject {
func touch()
}
- 변수뿐만 아니라 클로저와 관계해서도 발생하게 된다. 클로저에서 self 를 캡쳐하기 때문이다.(이때, 클로저 안에서 self 를 여러번 참조하더라도 실제로는 한 번만 참조된다.)
- 변수에 nil 을 할당해도, 클로저에서 self 를 강한 참조하고 인스턴스가 클로저를 강한 참조하기 때문에 발생.
어떻게 해결하나요?
- 약한 참조, 미소유 참조를 사용하여 해결할 수 있습니다.
출처: https://jusung.gitbook.io/the-swift-language-guide/language-guide/23-automatic-reference-counting
- 클로저에서 self 를 캡처하고, 약한 참조를 하게 되면 다음과 같이 파악할 수 있다.
- guard let 구문으로 self 를 강한 참조하게 되면 다음과 같이 파악할 수 있다.
728x90
반응형