[Swift] 클로저의 캡처링과 강한 참조

팔랑이·2024년 7월 4일
0

iOS/Swift

목록 보기
43/71
post-thumbnail

캡처링 (Capturing)

: 클로저가 주변 컨텍스트에 있는 변수나 상수의 참조를 캡처하고 저장하는 기능

  • 캡처링의 주요 목적은 클로저가 실행될 때 필요한 값을 유지하는 것
  • 클로저가 정의된 스코프 외부의 변수나 상수에 접근하여 캡처할 때, 해당 변수나 상수를 강하게 참조하여 해당 변수가 클로저의 생명주기동안 유지되도록 한다.

캡처 리스트 (Capture List)

: 클로저가 캡처할 변수와 그 참조 방법을 지정하는 리스트로, 이를 이용해 메모리 관리와 관련된 문제를 처리할 수 있다. 주로 강한 참조 순환을 방지하기 위해 사용

캡처리스트 구문

캡처리스트는 클로저 매개변수 목록 앞에 대괄호로 정의한다.

{ [captureList] (parameters) -> returnType in
    // 클로저 본문
}

캡쳐리스트를 사용하여 강한 참조 순환을 방지하는 예제

  1. 캡쳐리스트 사용 X
class MyClass {
    var value = 10
    
    func setupClosure() -> () -> Void {
        return {
            print("Value is \(self.value)")
        }
    }
}

var instance: MyClass? = MyClass()
let closure = instance!.setupClosure()
instance = nil

위 코드에서, instancenil로 설정되었지만 클로저가 self를 강하게 참조하고 있기 때문에 deinit이 호출되지 않고, MyClass 인스턴스가 메모리에서 해제되지 않는다. (RC == 1)

  1. 캡쳐리스트 사용 O
class MyClass {
    var value = 10
    
    func setupClosure() -> () -> Void {
        return { [weak self] in
            guard let self = self else { return }
            print("Value is \(self.value)")
        }
    }
}

var instance: MyClass? = MyClass()
let closure = instance!.setupClosure()
instance = nil

위 코드에서는 [weak self]를 사용하여 클로저가 self를 약한 참조로 캡처하도록 했고, instancenil로 설정되면 RC == 0으로 MyClass 인스턴스가 메모리에서 해제된다.

profile
정체되지 않는 성장

0개의 댓글