k-coding

Swift [weak self] 본문

iOS/Swift 정리

Swift [weak self]

chkhn_oiiu 2022. 2. 12. 18:11

Swift  [weak self]

 

코딩을 하다보면 클로져 안에서 weak self를 사용하던 경험이 정말 많을것입니다.

 

처음엔 이 weak self를 왜 쓰는지 모르고 따라서 썻었는데, 새롭게 공부하게 되어서 같이 공부하고자  포스팅 작성하게 되었습니다.

 

우선 이 전 제 포스트에 ARC에 관한 내용을 올린적이 있는데, 그 때 weak를 사용하는 이유가 순환참조를 막기 위해서라고 했습니다.

 

클로저 안에서 사용되는 weak self도 마찬가지로 순환참조로 인해 생기는 메모리 누수를 막기 위해서 입니다.

 

self를 캡쳐링하는 상황에서 self에 대한 순환참조가 발생되는것을 막고자 

 

스스로를 약한개체로 만들고자 할 때 사용하는게 weak self입니다.

예제

 

weak self는 주로 escaping 클로져에서 많이 나타나는데,

 

escaping 클로저 안에서 지연할당의 가능성이 있는 경우 (API 비동기 데이터 처리)등 상황을 칭합니다.

 

escaping 클로저가 아닌 일반적인 클로저들에서는 강력한 참조주기를 도입할 위험이 많지 않으므로

 

weak를 사용할 일이 매우 드뭅니다.

 

혹은 Delayed Deallocation도 조심해야 하는데

 

Delayed Deallocation은 클로저에서 공통적으로 나타나는 부작용  중 하나로,

 

클로저는 기본적으로 본문에서 참조하는 모든 객체를 캡쳐하기 때문에,

 

클로저 본문이나 범위가 살아있는 한 객체가 메모리에서 할당 해제되는 것을 방해한다.

 

이 경우에도 weak self를 사용하여 방지하여 줄 수 있다.

 

 

 

한가지 유의해야할 점은 weak self를 사용할 경우 대상이 되는 self는 옵셔널 형태가 된다는 것 입니다.

 

그 뒤에 그 대상에 self키워드를 사용할 때에는 그냥 self.가 아니라 self?. 로 옵셔널 체이닝 해주셔야합니다.

 

혹은

 

guard let으로 옵셔널 바인딩 해주셔도 됩니다.

 

다만 차이점이 조금 있다면

 

guard let인 경우 실질적으로 클로져가 시작되는 부분에서 nil인지 아닌지를 검사 하기 때문에

 

그 뒤에는 따로 검사를 하지 않아줘도 됩니다.

func example(completion: @escaping (String) -> Void){ [weak self] in
    guard let self = self else {
        return
    }
    let a = self.a
    let b = self.b
    let c = self.c
    }
}

 

하지만 옵셔널 체이닝으로 self뒤에 를 달경우 아래와 같이 3번 다 입력해주어야합니다

func example(completion: @escaping (String) -> Void){ [weak self] in
    let a = self?.a
    let b = self?.b
    let c = self?.c
    }
}

guard let을 이용할 경우 한번만 검사하면 끝날 것을 3번 상수가 더 많다면 그 이상도 검사해야하므로

 

조금 비효율적 일 수도 있습니다.

 

 

 

 

 

 

 

 

 

'iOS > Swift 정리' 카테고리의 다른 글

swift addChild  (0) 2022.03.13
Swift becomefirstResponder, resignFirstResponder 키보드 호출  (0) 2022.02.15
Swift @objc  (0) 2022.02.03
Swift Typealias ( 별명, 별칭 )  (0) 2022.01.14
Swift Associated Type  (0) 2022.01.14
Comments