반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

Closure에서의 Capture ( feat . reference type) [2/3] 본문

오뚝이 개발자/swift

Closure에서의 Capture ( feat . reference type) [2/3]

rriver2 2022. 5. 11. 15:36
반응형

저번 블로그 포스팅을 통해서 Closure가 무엇인지에 대해 알아봤다.

 

이번에는 Closure랑 좀 더 친해지는 ... 과정을 겪으려고 한다. ( 근데 아직 너무 어려움.... ^^ )

Closure의 Capture가 무엇인지, Closure가 reference type인지 몰랐다면..! 

같이 알아보자구용 ~~ 🥹🔥✨🧚🏻‍♀️

 

 

 Capturing Values 

Capturing Value를 살펴보기 위해 ... "the swift programming language"에서 한 예시를 가지고 왔다 !

 

이 makeIncrementer 함수를 호출하면, 클로저가 반환된다.

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

 

(참고

: 위 code은 중첩함수로 나타내어져 있는데,

중첩함수와 unnamedClosure 모두 value를 capture 하기 때문에

지금 설명하고자 하는 Capture에 대해 설명하는데에는 문제가 없지만,

나 같은 궁그미들을 위해 unnamedClosure 식도 밑에 추가로 두겠슘당.. ㅎㅎ)

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    let incrementer = {() -> Int in
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

 

1) 중첩 함수에 대한 이해 (with capture)

makeIncrementer 함수는 드래그한 부분 즉 , ()->Int인 closure을  반환하는 함수이다.

 

 

makeIncrementer내부에 있는 incrementer함수를 한번 떼어서 보자.

func incrementer() -> Int {
    runningTotal += amount
    return runningTotal
}

?? runningTotal ?? amount ?? 어디있어 ??

incrementer함수만 떼어서 보면 runningTotal이 무엇인지, amount가 뭔지 전혀 알 수 없다.

 

 

 

하지만 ,.,. 이렇게 함수를 실행하면 오류도 안뜨고 10이라는 결과도 잘 나온다...!

?? 이유가 뭐지 ??

 

이게 가능한 이유는 makeIncrementer() 중첩 함수의 scope에 있는

runningTotal과 amount을 capturing 했기 때문이다.

 

ㅎㅎ... 더 자세히 설명을 하면 !!

 

makeIncrementer 함수가 실행될 때 변수 runningTotal과 amount가 캡쳐링 되어

incrementer 함수에 두 주솟값이 공유가 된다. 

 

이 때문에 함수 바깥에 있는 변수나 상수들도 함수 내에서 사용이 가능하다. 

 

이때, runningTotal과 amount 모두 value type이지만 capturing될 때에는 reference type으로 캡쳐된다는 특징을 기억하자 !

 

 

 

 reference type인 Closure 

incrementByTen에 makeIncrementer()를 대입해보자 !

let incrementByTen : () -> Int = makeIncrementer(forIncrement: 10)

 

나는 closure을 변수에 넣는다는 것 조차 되게 낯설었는데,,

incrementByTen에는 Int, Double과 같은 하나의 값이 아니라

makeIncrementer의 반환값이었던 incrementer( ) 클로져 즉, ( )->Int 가 들어가 있다고 생각하면 연상하기 쉬울 것이다..

 

(아래 그림 드래그 한 부분이 들어가 있은 거다!)

 

 

자 이제 실행을 해보자 !

ㅎㅎ 뭔지 잘 모르겠었다...  그냥 잘 모르겠었다.... 나는 내가 뭘 모르는 지도... 모르겠었다.

 

 

계속 뚫어져라 보고 있으면 2가지 의문점이 드는데,, 가려운 부분을 긁어보자 ㅎㅎ!!

 

의문점 1)  왜.. 값이 10 -> 20 -> 30 누적되어 증가하는 거지 ???

incrementByTen를 호출할 때마다 값이 계속 증가하는데,,, 왜 증가할까?? ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

그 이유는 Capturing Value 때문이다 !

앞서 말했던 거처럼 함수가 실행될 때 변수 runningTotal과 amount가 캡쳐링 되어 변수가 공유되기 때문에 계산이 누적되기 때문이다.

func incrementer() -> Int {
    runningTotal += amount
    return runningTotal
}

여기서 runningTotal과 amount의 값이 value 타입으로 저장되어 있는 게 아니라 reference type으로 저장되어 있기 때문에

저장되어 있는 주솟값에 접근하여 값을 증가시키기 때문에 값이 누적되어 계산이 이루어진다.

 

 

+ 당연한 말이지만, 새로 함수를 호출하면 또 캡쳐링을 하기 때문에 incrementByTen()와 incrementByTen2()는 다른 Int의 값이 나온다 .

 

 

 

의문점 2) incrementByTen은 Int형 상수인데 왜 값이 변하는 거지 ?

공문 내용을 읽어보면 , 변수나 상수에 함수나 클로져를 넣으면 reference type으로 저장이 된다.!

 

따라서 incrementByTen가 let이라도 계속 값이 바뀔 수 있었던 거고,

이렇게 변수에 넣으면 그 값이 저장되는 게 아니라 주솟값이 저장되기 때문에 이전의 값에서 이어 증가된 40이 출력되게 된다.

 

 

 

 

 

오늘 포스팅한 내용을 정리해보자면, 이렇게 작성할 수 있을 거 같다 :)

      특징
Closure named closure ( function ) Global function capture(x)
Nested function capture(o)
unnamed closure closure expression capture(o), 경량식

 

 

+ swift 문서에 강한 순환 참조가 적혀 있는데 지금 내 머리로는 이해를 할 수 없어서 ㅠㅠ

이 부분은 다음에... 포스팅을 해보려고 한다.

 

+ reference type 부분은 나중에 메모리 공부를 좀 더 해서 그림을 통해 좀 더 디테일한 설명을 하려 한다... !

반응형

'오뚝이 개발자 > swift' 카테고리의 다른 글

removeLast() vs popLast()  (0) 2022.05.24
[2/2] optional chaining  (6) 2022.05.14
[1/2] Optional unwrapping  (0) 2022.05.14
Closure 넌 누구냐 ! [1/3]  (0) 2022.05.11
Property(1/4) - > StoredProperty  (0) 2022.04.27
Comments