728x90
Capturing에 대해 알아 보겠습니다.
CaptureList
클로저는 정의 된 주변 컨텍스트에서 상수 및 변수를 캡처(Capturing) 할 수 있습니다.
그런 다음 클로저는 상수와 변수를 정의한 원래 범위가 더 이상 존재하지 않더라도 본문 내에서 해당 상수와 변수의 값을 참조하고 수정할 수 있습니다.
Value Type Capture
var a = 1
var b = 2
var c = 3
var result = 0
// 1,2,3,0
print("초기화 값 :", a, b, c, result)
print("a, b 만 캡쳐")
let valueCapture = { [a,b] in
result = a + b + c
print("내부 : ", result)
}
//1번째 호출
valueCapture() // 내부 6
a = 2
b = 3
c = 4
result = a + b + c
print("변경 값 :", a, b, c, result)
//2번째 호출
valueCapture() // 내부 7
valueCapture클로저에서 []을 이용하여 a, b를 값을 캡처했습니다.
1번째로 valueCapture를 호출했을때 내부 값은 6으로 나왔고, a,b,c의 값을 변경 후 2번째로 valueCapture를 호출했을때 a,b는 여전히 1,2로 캡처되어있고 c변수만 4로 변경되어져 내부 값이 7로 변경되어진걸 볼 수 있습니다.
Reference Type Capture
클로저는 기본적으로 Reference Type입니다.
클로저 바깥의 값을 사용할 때는 해당 값을 참조하여 사용하게 됩니다.
final fileprivate class RefType {
var number = 0
}
fileprivate var x = RefType()
fileprivate var y = RefType()
print("초기화 값 :", x.number, y.number)
let refCapture = { [x] in
print("클로저 내부 값 :", x.number, y.number)
}
x.number = 5
y.number = 7
print("변경 값 :", x.number, y.number)
refCapture()
print("실행 이후 값 :", x.number, y.number)
초기화 값 : 0 0
변경 값 : 5 7
클로저 내부 값 : 5 7
실행 이후 값 : 5 7
refCapture는 [x]를 캡처하고 있음에도 불구하고,
클로저 내부의 x.number, y.number는 외부의 x.number, y.number를 참조하고 있습니다.
이러한 Reference Type의 특성으로인해 원치않는 값의 변화가 생길 수 있습니다.
Binding an arbitrary expression
let captureBinding = { [z = x] in
print(z.number)
}
let captureWeakBinding = { [weak z = x] in
print(z?.number ?? 0)
}
let captureUnownedBinding = { [unowned z = y] in
print(z.number)
}
captureBinding() // 5
captureWeakBinding() // 5
captureUnownedBinding() // 7
'Swift' 카테고리의 다른 글
[Swift] 타입체크(TypeCheck) (0) | 2019.07.22 |
---|---|
[Swift] Closure - 3 (NoEscaping, Escaping, AutoClosure) (0) | 2019.07.22 |
[Swift] Closure - 1 (Basic) (0) | 2019.07.22 |
[Swift] 옵셔널(Optionals) (0) | 2019.07.22 |
[Swift] 접근제어(Access Control) (0) | 2019.07.20 |