mutating : struct나 enum과 같은 값타입에서 사용💡 구조체(Structs)나 열거형(Enum) 내에서 메서드(Method)가 해당 구조체
또는 열거형의 속성을 수정할 수 있도록 한다.
📌 캡처(Capture)
흔히 들어온 캡처와는 느낌이 살짝 다를 수 있다. 캡처한다는 말을 들으면 스냅샷이 제일 먼저 떠오른다. 그 순간을 그대로 사진처럼 담아 값도 정의되는 순간 그대로 가져올 것만 같은데, 실제로 그렇지 않다.
여기서 말하는 캡처는, 해당 값이 사라지지 않도록 잡아둔다는 뜻이 강하다. 사진을 찍다의 capture가 아니라, 뭔가를 잡을 때의 capture에 가깝다.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
makeIncrementer 라는 함수는 () -> Int 타입을 반환하는 함수로, 클로저를 반환한다고 볼 수 있다. 읽어보면 incrementer 라는 함수를 반환하고 있는걸 확인할 수 있다.incrementer 안을 보면, incrementer 외부에 있는 runningTotal이라는 변수를 참조하고 있다. 그러면 incrementer는 runningTotal과 amount를 캡처했다, 고 생각할 수 있을 것이다.let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen() //returns a value of 10
incrementByTen() //returns a value of 20
incrementByTen에는 makeIncrementer가 만들어준 runningTotal에 10씩 늘려주는 incrementer 클로저를 저장하게 된다.
그냥 생각해보면 makeIncrementer가 끝난 후엔 runningTotal와 amount는 사라져야 하는데, 사라지지 않고 클로저가 계속 이용하고 있다.
그 이유가 바로 incrementByTen에 저장된 클로저가 runningTotal을 참조하고 있기(RC를 하나 늘려주고 있기) 때문이다.
여러번 불러도 runningTotal 값이 0으로 초기화되지 않고 그냥 10씩 늘어나는 것도 incrementByTen이 동일한 변수를 참조하고 있기 때문이다.
만약 처음에 생각했던대로 잡아두는 방식이 아니라 환경을 사진처럼 찍어두는 것이었다면, runningTotal의 값은 실행할 때마다 0으로 시작했을 것이다.
var defaultFunction: () -> () = { print("출력") }
func escapingFunc(closure: @escaping () -> ()) {
// 클로저를 실행하는 것이 아니라 defaultFunction 변수에 저장.
// 함수는 변수와 달리 기본적으로 외부 할당이 불가능
defaultFunction = closure
}
escapingFunc() 함수의 closure 인자로 전달됨closure이 defaultFunction 변수에 저장됨escapingFunc() 함수가 값을 반환하고 종료됨closure은 아직 실행되지 않음closure은 함수의 실행이 종료되기 전에 실행되지 않기 때문에 escaping 클로저, 다시말해 함수 밖(escaping)에서 실행되는 클로저 입니다.