- This topic has 4개 답변, 2명 참여, and was last updated 4 years, 9 months 전에 by Lena.
-
글쓴이글
-
-
Lena참가자
- 글작성 : 4
- 답글작성 : 5
오늘은 메모리 관점에서 클로저에 대해서 학습했습니다.
1. 클로저는
`swift
func makelncrementer(forlncrement amount: Int) -> (() -> Int) {
var runningTotal =0
func incrementer() -> Int {
runningTotal += amount return runningTotal
}
return incrementer
}let incrementByTwo: (()->Int) =makelncrementer(forlncrement: 2)
let sameWithlncrementByTwo: (() -> Int ) = incrementByTwo
let first: Int =incrementByTwo() // 2
let second: Int =sameWithlncrementByTwo() // 4
`
클로저는 자신이 정의된 위치의 주변 문맥을 통해 상수나 변수를 획득(capture)할 수 있습니다. 값 획득(Capture)을 통해 클로저는 주변에 정의한 상수나 변수가 더 이상 존재하지 않더라도 해당 상수나 변수의 값을 자신 내부에서 참조하거나 수정할 수 있습니다.상수에 클로저를 할당한다는 것은 클로저의 값을 할당하는 것이 아니라 해당 클로저의 참조를 할당하는 것입니다.
2. 클로저는 클래스와 마찬가지로 Reference Type
값 전달할 때 마다 stack에 주소가 복사됩니다.
참조 방식에서 ‘참조’는 stack에 저장되어있는 주소를 의미합니다.3. 클로저의 캡쳐와 캡쳐리스트를 통한 캡쳐
`swift
var firstOne = 0
var secondOne = 0
let closure = {print (firstOne,secondOne)}
firstOne = 1
secondOne = 2
closure() // 결과 : 1,2
`
closure 상수에 저장된 클로저는 firstOne, secondOne 두 상수를 캡쳐합니다.
클로저가 값을 캡쳐할 땐 복사본이 아니라 참조(값의 주소, reference)가 전달합니다. 두 변수를 변경하고 클로저를 호출하면 클로저가 생성된 시점에 두 변수에 저장되어있던 값이 아니라 변경된 현재 값이 출력됩니다.`swift
var firstOne = 0
var secondOne = 0
let closure = { [firstOne] in print (firstOne, secondOne)}
firstOne = 1
secondOne = 2
closure() // 결과 : 0,2
`
하지만 캡쳐 리스트(Capture List)를 통해
firstOne
을 캡쳐하면 이전과 달리 참조가 전달되지 않습니다. 왜냐하면firstOne
에 저장되어있는 값과 동일한 값을 가진 상수 복사본이 전달되기 때문입니다. 그래서 클로저를 선언한 후(3번째 라인)에fisrtOne
값을 변경하더라도, 변경되지 않은 클로저에서 캡쳐된firstOne
의 값이 출력됩니다. 즉, 캡쳐 대상으로 지정한firstOne
은 값이 복사되서 전달됐으므로0
이 출력됩니다.3. 클로저 내
self
`swift
class Person{
var name = “Lena”
var job = “developer”
lazy var nameTag: () -> String = {
return self.name + self.job
}
}
`
클로저는
self
키워드를 통해 인스턴스 속성에 접근합니다.self
는 인스턴스 자체를 나타내는 속성으로, 클로저에서 사용하면self
가 캡쳐됩니다. 위 예제 코드(3번)에서는self
가Person
이라는 클래스이고 이 클래스 인스턴스를 캡쳐합니다. 그리고 이 클래스의 속성인name
과job
에 접근합니다. 클로저는 자신의 실행이 종료될 때 까지 self가 메모리에 유지되도록 강한참조로 캡쳐합니다. 이 클로저는 인스턴스 속성(Person
이라는 클래스의 프로퍼티)에 저장됩니다.
(3번 예제 코드는 클로저의 강한참조 순환문제가 일어나는 코드입니다. 이 문제는 Capture List로 해결할 수 있습니다.)참고한 자료 :
‘스위프트 프로그래밍 3판’ (지은이: 야곰)
‘Closures — The Swift Programming Language (Swift 5.2)’
https://docs.swift.org/swift-book/LanguageGuide/Closures.html2020-03-02 오전 1:30 #2079
-
-
글쓴이글
- 답변은 로그인 후 가능합니다.