⭐️들어가기에 앞서 참조 타입(Reference Type)인 클로저(Closures)는 메모리의 힙(Heap) 영역에 저장된다는 점을 꼭 기억하세요.
클로저 외부에 정의된 변수(상수)를 클로저가 참조하여 지속적으로 사용할 때 해당 변수의 주솟값를 클로저의 힙(Heap) 영역에 저장하게 되며, 이러한 현상을 캡처(Capture) 현상이라고 부릅니다.
클로저뿐만 아니라 함수를 변수에 할당하여 사용할 경우 해당 변수는 메모리의 힙 영역에 저장되기 때문에 캡처 현상이 발생할 수 있습니다.
✅ Swift의 캡처(Capture) 현상
var sum = 1 // 클로저 외부의 변수 var add = {(n: Int) -> Int in sum *= n // 클로저 내부에서 외부 변수(sum)를 사용하기 때문에 변수(sum)를 Heap 영역에 저장 => 캡처 현상 발생 return sum } add(10) // 10 => 1*10 add(20) // 200 => 10*20 add(30) // 6000 => 10*20*30 // Heap 영역의 sum 변수를 참조해서 사용하기 때문에 값이 중첩된다.
클로저 외부에 정의된 변수(상수)를 클로저가 참조하여 지속적으로 사용할 때 해당 변수의 값 자체를 클로저의 힙(Heap) 영역에 저장하게 되며, 이러한 현상을 캡처 리스트(Capture List)에 의한 캡처(Capture) 현상이라고 부릅니다.
변수의 주솟값이 아닌 변수의 데이터값을 힙(Heap) 영역에 저장하기 때문에 외부에서 데이터값을 변경하기 힘들다는 특징을 가지고 있습니다. (외부로부터의 접근 보호)
캡처 리스트를 구현할 때는 대괄호[ ]를 사용합니다.
✅ 캡처 리스트의 형태
{[캡처리스트(외부 변수)] in <실행 코드> }
{[캡처리스트(외부 변수)] (파라미터) -> 반환 타입 in <실행 코드> }
✅ 일반적인 캡처(Capture) 현상
외부 변수의 주솟값을 힙(Heap) 영역에 저장
var n = 0 var numberPrint = { print("반환값: \(n) 입니다.") // 클로저 내부에서 외부 변수 사용 } numberPrint() // 반환값: 0 입니다. n = 10 numberPrint() // 반환값: 10 입니다. n = 100 numberPrint() // 반환값: 100 입니다.
✅ 캡처 리스트(Capture List)에 의한 캡처(Capture) 현상
외부 변수값을 힙(Heap) 영역에 저장
var n = 0 var numberPrint = { [n] in // 캡처 리스트 구현 print("반환값: \(n) 입니다.") // 클로저 내부에서 외부 변수 사용 } numberPrint() // 반환값: 0 입니다. n = 10 numberPrint() // 반환값: 0 입니다. n = 100 numberPrint() // 반환값: 0 입니다.