하루를살자

[Swift] Closure 의 Capture, CaptureList 본문

Swift

[Swift] Closure 의 Capture, CaptureList

Kai1996 2022. 8. 6. 16:32

Capture

클로저의 캡처 방식은 아래와 같은 코드가 주어질때
func doSomething() {
//1
    var num: Int = 0
    print(address(of: &num))
    print("num check #1 = \(num)")
    
//2
    let closure = {
        print(address(of: &num))
        print("num check #3 = \(num)")
    }
    
    num = 20
    print("num check #2 = \(num)")
    closure()
}

1.0: num 은 0 이라는 int 타입의 값을 생성하면서 메모리에 값이 저장된다. 

2.0: Closure 안에 외부 변수인 num 을 사용해서 print 하게 되는데, closure 내부의 scope 안에 선언된 외부 변수를 사용하게 되는데, 이 과정을 "캡처" 라고 부른다. 

이때 Closure 는 Value/Reference 타입 상관없이 캡처하는 값들을 참조 하게 되는데 이것을 ReferenceCapture 라고 한다.  따라서 아래 스크린샷에서 num check #3 가 불려지기전에 num 이 참조하는 메모리 주소값이 같은것을 확인할수 있다. 

 

결과값 및 실제 메모리 주소값 비교

 

CaptureList 

캡처 리스트는 아래처럼 클로저 의 "in" 키워드 앞에 괄호에 감싸져있는 변수들을 말한다.

이를 사용하면 Copy 해서 캡처할 변수를 명시 해줄수 있고 Value Type 이 캡쳐 될때 상수로 캡쳐된다. 

var closure = { [variable1, variable2, variable3, ...] in }
Value Type in captureList
func doSomething() {
  var num: Int = 0
  var num2: Int = 1
  print("num check #1 = \(num), \(num2)")
  let closure = { [num2] in
    print("num check #3 = \(num), \(num2)")
  }
  num = 20
  num2 = 40
  print("num check #2 = \(num), \(num2)")
  closure()
}

1. OuterVariable 초기화

 closure 내부의 num 은 외부 num 변수를 가르키고 있다. 

2. CaptureList 값 copy

captureList 의 num2 값은 현재 외부 num2 값 을 copy 한 상수 로 가지고 있다. 

 

따라서 CapturedList 에 선언된 num2 는 외부 num2 변수의 값이 바뀌었더라도 closure 가 선언되었을 당시의 num2 값, "1" 을 print 하게 된다. 그에 반대로 num 은 외부 num 변수를 캡쳐 하고 있기 때문에 업데이트된 값 20 을 프린트 하게 된다 .

ReferenceType In captureList
class Person {
  var name: String
  init(name: String){
    self.name = name
  }
}

func doSomething() {
  let person1 = Person(name: "Kai")
  print("name check #1 = \(person1.name)")
  let closure = { [person1] in
    print("name check #3 = \(person1.name)")
  }
  person1.name = "kim"
  print("name check #2 = \(person1.name)")
  closure()
}

ReferenceType 은 captureList 안에 선언됐다고 해도 ReferenceCapture 가 된다. 

Result of reference Type In captureList

그렇다면 ReferenceType 은 CaptureList 안에 지정 할 필요가 없을까? 다음으로 정리할 글은 

클로저 인스턴스간의 관계 와 weak self, unowned self 등을 왜 사용하는지 알아볼것이다

 

 

참조 

https://babbab2.tistory.com/50

https://shantaram-kokate-swift.medium.com/capture-list-in-swift-a7d7d1328c84

 

Capture list In Swift

What is a capture list?

shantaram-kokate-swift.medium.com

 

'Swift' 카테고리의 다른 글

[Swift] 강한 순환 참조  (0) 2022.08.06
ARC (Automatic Reference Counter)  (0) 2022.08.06
[Swift] LinkedList  (0) 2022.08.05
[Swift] Expansive DateFormatter : 어떻게 사용해야할까?  (0) 2022.06.09
Swift - Closure (2) : Trailing Closure  (0) 2022.02.27
Comments