코딩하는 제리

[Swift] swift 클로저 캡쳐 본문

iOS/SwiftUI

[Swift] swift 클로저 캡쳐

JerryCho 2022. 1. 7. 14:08

// Value 타입 (struct, enum) : 값의 복사
// Reference 타입 (class) : 값의 참조

// 클로저에서 값을 캡쳐한다?

// 클로저 내부에서 외부 변수인 num 변수를 사용(print)하기 때문에
// num의 값을 클로저 내부적으로 저장하고 있는데,
// 이것을 클로저에 의해 num의 값이 캡쳐 되었다고 표현함.
// message 변수는 클로저 내부에서 사용하지 않기 때문에 캡쳐되지 않음.
func doSomething() {
	var message = "Hi, Jerry"
    
    // 클로저 시작
    var num = 10
    let closure = { print(num) }
    // 클로저 끝
    
    print(message)
}

// 클로저는 값을 캡쳐할 때
// Value/Reference 타입에 관계 없이 Reference Capture 한다.
// num은 Int 타입의 구조체 형식이고, 이는 곧 Value 타입이기 때문에,
// 값을 복사해서 저장해야 되는 것이 일반적이다.
// 그러나 클로저는 Value/Reference 타입에 관계 없이 캡쳐하는 값을 참조. (Reference Capture)
func doSomething() {
	var num: Int = 0
    print("num #1 = \(num)")
    
    let closure = {
    	print("num #3 = \(num)")
	}
    
    num = 20
    print("num #2 = \(num)")
    closure()
}
// closure()를 실행하기전에 num 변수 값을 20으로 변경
// num #1 = 0
// num #2 = 20
// num #3 = 20
// 클로저 내부 또는 외부 한곳에서 num 변수의 값을 변경하면
// 내부/외부 num의 값이 다 바뀐다. (Reference Capture/Type)
// Value 타입으로 캡처

// 클로저 캡쳐 리스트 (Capture Lists)
// []를 이용해 캡쳐할 멤버를 나열 이때 in 키워드도 함께 작성
let closure = { [num, num2] in

// 예시
func doSomething() {
	var num: Int = 0
    print("num #1 = \(num)")
    
    let closure = { [num] in
    	print("num #3 = \(num)")
    }
    
    num = 20
    print("num #2 = \(num)")
    closure()
}
// num #1 = 0
// num #1 = 20
// num #1 = 0
// closure()를 실행하기 전에 외부 변수 num을 20으로 변경했지만
// 클로저의 num에는 영향을 주지 않음.
// Value Type으로 캡쳐할 경우 Const Value Type(상수)으로 캡쳐함
// 클로저 내부에서 Value 캡쳐된 값을 변경할 수 없다.

// Reference Type의 값을 캡쳐할 수는 없나?
// Reference Type을 Capture Lists에 작성하면 Value 캡쳐가 되지 않는다.(unknown)
// 캡쳐 리스트를 작성한다 해도, Reference Type은 Reference Capture를 한다.

 


 

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

[Swift] swift 옵셔널  (0) 2022.01.07
[Swift] swift 튜플  (0) 2022.01.07
[Swift] swift 클로저 - @autoclosure, @escaping  (0) 2022.01.04
[Swift] swift 클로저  (0) 2022.01.03
[Swift]열거형(enum)/rawValue  (0) 2022.01.03
Comments