본문 바로가기
Xcode/Swift - PlayGround

PlayGround) Closure 에 대해서 알아보자 3부 (Escaping)

by 후르륵짭짭 2020. 8. 4.
728x90
반응형

docs.swift.org/swift-book/LanguageGuide/Closures.html

 

Closures — The Swift Programming Language (Swift 5.3)

Closures Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages. Closures can capture and store referen

docs.swift.org

안녕하세요 후르륵짭짭 입니다.

드디어 Closure에 대해서 부족하지만 제가 아는 내용을 거의 다 전파 할 것 같습니다.

추가적으로 알게 된 내용이 있을 경우 다시 포스팅 하겠습니다.

 

** Escaping Closure **

Escaping Closure 는 제가 참 이해하기 어려운 부분이였습니다....

API 통신을 공부하는데 다들 Escaping Closure를 사용하는데,,, 저게 먼 소리지 싶었죠 ㅎㅎㅎ

그래서 아주 많은 실험을 했습니다 ㅎㅎㅎㅎ

일단 Escaping Closure란 두망 갈 수 있는 Closure 입니다

2부에서 nonEscaping Closure에 대해서 다룬 것으로 기억 납니다. 

nonEscaping 클로저는 도망 갈 수 없이 일정한 순서대로 수행된다고 말씀드렸습니다.

hururuek-chapchap.tistory.com/38?category=909177

 

Swift) Closure에 대해서 알아보자 2부 (nonEscaping)

안녕하세요 후르륵 짭짭 입니다. 오늘은 클로저의 noneEscaping 함수에 대해서 알아보려고 합니다! nonEscaping은 딱 봐도 "도망칠 수 없는"으로 해석이 되져? 예! 맞습니다. nonEscaping 함수는 도망 칠수 �

hururuek-chapchap.tistory.com

히자만 Escaping은 다릅니다. 

func escapingFunc(number :Int , escapingHandler : @escaping (Int) -> ()) -> Int{
    
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        
        print("escaping Start")
        escapingHandler(number)
    }
    
    return number
    
}

let result = escapingFunc(number: 200) { (number) -> () in
                print(number + 1000)
            }
print("escaping 결과 : \(result)")

이 코드를 보면 escapingFunc에서 정수를 받고 그 옆에 @escaping 이라고 되어 있습니다.

@escaping이 바로 Escaping Closure를 의미하는 겁니다.

그리고 옆에 (정수)를 받아서 (Void)를 반환한다고 되어 있네요!

머 여기 까지는 nonEscaping 이랑 동일합니다. (nonEscaping으로 한다면 아마 오류가 나올 겁니다 ㅎㅎㅎ)

하지만!!! 함수 안에 Thread가 있고 이 Thread는 2초 뒤에 실행이 됩니다.

이렇게 언제 끝마칠지 모를 때!!! Escaping 함수를 사용합니다.

그래서 API 통신에서 escaping 함수를 많이 사용 되는 겁니다. 다운로드를 언제 마칠지 모르는 상황이기 때문이져!

 

그러면 함수 코드를 번호로 표현 해보겠습니다.

func escapingFunc(number :Int , escapingHandler : @escaping (Int) -> ()) -> Int{
    (1)
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        (4)
        print("escaping Start")
        (5)
        escapingHandler(number)
    }
    (2)
    return number
    
}

let result = escapingFunc(number: 200) { (number) -> () in
                (6)
                print(number + 1000)
            }

(3)
print("escaping 결과 : \(result)")

그래서 순서가 이렇게 됩니다.

(1)처음에 2초 뒤에 실행시킬 Thread를 만나고 (2)바로 정수를 반환 합니다. 그리고 (3)정수를 출력합니다. 

아직 2초가 안 지났습니다.  그리고 2초가 지난 시점에 escapingHandler 클로저를 실행 시키게 됩니다.

그래서 결과는 이렇게 나옵니다.

escaping 결과 : 200
escaping Start
1200

 

 

그리고 Escaping 클로저는 일단 반환을 보통 -> ()로 합니다. 

어차피 클로저 부분에서 수행 해주면 되기 때문입니다.

만약 (Int) -> (Int) 이렇게 해서 반환 값을 받도록 코드를 구현하더라도

"Unexpected non-void return value in void function"

이런 오류가 나올 겁니다. 어찌 보면 당연한 오류겠죠??? ㅎㅎㅎㅎ

 

지금 까지 Escaping Closure 에 대해서 다뤄 봤습니다.

정말 수고 많으셨습니다.

끝이 아닙니다 그런데 ㅎㅎㅎ

4부에는 Escaping Closure 랑 Enum 그리고 Generics 를 사용한 

오류 Handler를 배워 보도록 하겠습니다.

728x90
반응형

댓글