강한참조의 예와 리테인 사이클(retain cycle) , 레퍼런스 사이클(reference cycle) #클로저

임혜정·2024년 6월 15일
0

강한참조의 예시

import UIKit

class MyViewController: UIViewController {
    var completionHandler: (() -> Void)?
    // MyViewcontroller클래스가 completionHandler라는 클로저 속성을 가짐

    override func viewDidLoad() {
        super.viewDidLoad()
        
        startSomeOperation()
    }
    
    func startSomeOperation() {
        completionHandler = {
            self.doSomething()
        }/*이 메서드가 클로저를 설정하면서 self를 캡쳐하는데 
        이로인해 클로저가 self에 대한 강한 참조하고 
        self는 completionHandler를 강한참조하며 
        참조 사이클이 발생한다.*/
    }
    
    func doSomething() {
        print("Doing something")
    }
    
    deinit {
        print("MyViewController is being deinitialized")
    }
}

메모리 누수 문제 - 뷰 컨트롤러가 화면에서 사라져도 completionHandler 클로저가 self를 강한 참조하고 있어서 MyViewController인스턴스는 메모리에서 해제되지 않는다.

메모리 누수가 심해질 경우 > 느린 반응 속도> 사용자 짜증유발, 베터리소모증가, 품질 기준 미달로 앱스토어 승인 지연 가능성

해결 방안

import UIKit

class MyViewController: UIViewController {
    var completionHandler: (() -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        startSomeOperation()
    }
    
    func startSomeOperation() {
        // self를 약한 참조로 캡처하여 강한 참조 사이클을 방지
        completionHandler = { [weak self] in
            self?.doSomething()
        } // self?를 사용하여 안전하게 접근.
    } //따라서 뷰 컨트롤러가 화면에서 사라질 때 정상적으로 메모리 해제된다
    
    func doSomething() {
        print("Doing something")
    }
    
    deinit {
        print("MyViewController is being deinitialized")
    }
}

누수 방지 - 뷰 컨트롤러가 해제되면 클로저 내에서 참조하고 있던 self도 nil이 되어 강한 순환 참조가 발생하지 않게된다.


리테인 사이클 (Retain Cycle)

리테인 사이클은 두 개 이상의 객체가 서로를 강하게 참조하여 메모리에서 해제되지 않는 상황을 말한다. Swift의 ARC(Automatic Reference Counting) 메커니즘은 객체의 참조 횟수를 추적하여 참조 횟수가 0이 되면 메모리를 해제한다. 그러나 리테인 사이클이 발생할 경우, 참조 횟수가 0이 되지 않아 메모리 해제가 되지 않고 메모리 누수가 발생할 수 있다.

레퍼런스 사이클 (Reference Cycle)

레퍼런스 사이클은 객체들이 서로를 참조하여 강한 참조 사이클을 형성하는 상황을 말한다. 이로 인해 객체들이 메모리에서 해제되지 않고 지속적으로 남아 있게 되어 메모리 누수가 발생한다.

리테인 사이클과 레퍼런스 사이클은 사실상 같은 개념이며 이는 메모리 관리에서 중요한 문제다. 이를 해결하기 위해 약한 참조(weak reference)나 미소유 참조(unowned reference)를 사용하여 방지할 수 있다

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️

0개의 댓글