본문 바로가기

iOS/Swift

[weak self] 왜 쓸까!!

어느순간부터 개발을 할 때 [weak self] 를 거의 무조건 붙히는데여

메모리 누수와 참조 문제와 관련이 있다고 공부했었던 기억이 있는데 잘 기억도 안나고.. 그냥 무의식적으로 항상 넣고 있길래 정리를 한번 해보려고 합니다.

여기서는 메모리에 관한 부분은 다루지 않고 참조에 관한 내용만 다뤄보도록 하게씀

(ARC 이런건 따로 정리해 볼 예정)

 

클로저 내부에서 외부 변수를 사용하게 되면 변수를 클로저 내부적으로 저장을 하고,

이때 해당 변수의 타입(값, 참조)에 상관없이 참조타입으로 memory capture를 하게 됩니다.

 

참조에 대해서 코드로 설명을 더 해보겠음!

var a = 5

let closure = {
    print(a)
}

print(a) // 5

a = 10
closure() // 10

위와 같은 코드에서 a 는 Int 타입이므로 값 타입임.

여기서 closure는 a의 값을 캡쳐할텐데 이때 참조 타입으로 캡쳐를 진행함.

따라서 closure()를 실행하면 참조 타입이기 때문에 5가 아닌 수정된 10의 값이 출력됨

이때 Capture List를 이용해 값타입으로 캡쳐도 가능함.

Capture List

리스트에 나열된 변수는 클로저가 사라질때까지 변경되지 않고 유지가 됨.

var a = 5

let closure = { [a] in
    print(a)
}

print(a) // 5

a = 10
closure() // 5

[ ] 대괄호를 이용해 값타입으로 캡쳐할 변수를 명시하면 위와같이 값 타입 캡쳐가 가능해짐

주의할점은 Const Value Type이라는 거임

값 타입이긴 하나 상수로 캡쳐가 되어서 closure 내부에서 a의 값을 변경할 수 없음


그럼 다시 돌아와서 [weak self] 는 강한 순환 참조를 해소하기 위해 사용하는데

강한 순환 참조는 아래의 그림과 같이 둘 이상의 객체가 서로를 강하게 참조할 경우 발생하게 됨 (메모리 해제되지 않음)

이때 weak를 사용하여 RC의 증가를 막을 수 있고, 위에서 살펴봤던 캡쳐 리스트를 이용해서

클로저 내부의 강한 순환 참조를 해결할 수 있음.

 

[weak self]는 self에 대한 참조를 캡쳐 리스트를 이용해 weak로 캡쳐를 하는거임!!

 

이때 weak는 nil의 가능성이 있는 옵셔널 타입이므로 self에 옵셔널 바인딩(self?.)을 해주어야 함

 

그럼 얘는 언제언제 써야할까요?

메모리 누수가 발생할 수 있는 경우 사용해야 함.

non escaping closure (함수가 끝나기 전에 실행되는 클로저)는 함수의 종료 전 클로저도 메모리 할당이 해제되므로 키워드를 붙힐 필요가 없음

escaping closure 안에서 사용되며 이 역시도 모든 경우에 필요한 것은 아님.

코드로 예시를 작성해볼까 하다가 아래 잘 정리된 글을 발견해서 공유하고 넘어가도록 하게씀미다!

 


[weak self] 무조건 사용하는게 맞는걸까? 🤔

 

[weak self] 무조건 사용하는게 맞는걸까? 🤔

클로져에서 self를 캡쳐할 때 를 사용하는 경우는 순환 참조를 방지하기 위해 약한 참조로 클로져 내부에서 해당 클래스의 인스턴스를 사용할때 입니다. 클로져에서 약한 참조를 이용해 특정 인

noah0316.github.io

[Swift] [weak self]는 언제 사용할까?

 

[Swift] [weak self]는 언제 사용할까?

우리는 무의식적으로 [weak self]를 활용할 때가 매우 많습니다. 흔히 [weak self]를 활용하는 이유를 메모리 릭이라고 합니다. 그렇다면, 우리는 항상 [weak self]를 활용하면 될까요? [weak self]를 언제 사

longlivedrgn-miro.tistory.com

자동 참조 카운팅 (Automatic Reference Counting)

 

자동 참조 카운팅 (Automatic Reference Counting) - Swift

이것을 가능하게 하려면 프로퍼티, 상수, 또는 변수에 클래스 인스턴스를 할당할 때마다 해당 프로퍼티, 상수, 또는 변수는 인스턴스에 강한 참조 (strong reference) 를 만듭니다. 참조는 해당 인스

bbiguduk.gitbook.io

 

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

Type Erasure, Opaque Type  (0) 2024.07.03
Access Control(접근제어자)  (0) 2024.06.23
Metatype(.self, .Type, .Protocol)  (1) 2023.11.08
Swift Xcode 프로젝트명 바꾸기  (0) 2023.08.01
Swift Generic이란??  (0) 2023.07.13