본문 바로가기
IOS

[iOS] Closure, Trailing Closure, Escaping Closure - 에이젠

by eigen96 2022. 9. 14.
728x90

Android 개발에서 Kotlin을 그동안 사용해오다가 

iOS개발의 필요성을 느끼고 Swift를 처음 접한 당시 

굳이 클로져라는 단어를 붙이는 게 무슨의미가 있나 싶었습니다.

코틀린의 람다함수랑 비슷한 것 같죠?

 

클로저를 검색해서 정의를 살펴보면 아래와 같습니다.

 

클로저는 사용자의 코드 안에서 전달되어 사용할 수 있는 로직을 가진 중괄호“{}”로 구분된 코드의 블럭이며, 일급 객체의 역할을 할 수 있다.
- 일급 객체는 전달 인자로 보낼 수 있고, 변수/상수 등으로 저장하거나 전달할 수 있으며, 함수의 반환 값이 될 수도 있다.
- 참조 타입이다.
- 함수는 클로저의 한 형태로, 이름이 있는 클로저이다.

일급객체?

중괄호 코드블럭? 그냥 함수가 실행되는 바디 부분 아닌가?

음... 함수가 클로저의 형태라고 되어있긴하군....

처음엔 와닿지 않았습니다.

 

기본적인 클로저 형태는 아래와 같습니다.

let 변수명 : 반환타입 = {
	return 반환값
}()

let 변수명2 = { (매개변수명: 타입) -> 반환타입 in 
	return 반환값
}()

let 변수명3 : (매개변수타입) -> Void = { (매개변수명: 타입) in
	//~~~
	return
}

쉽게 생각하면 클로저는 메소드라고 생각해도 될 것 같습니다.

클로저를 사용할 때는 해당 클로저의 이름만 입력하면 되는 것이죠.

그렇다면 일급객체는 뭘까요??? 아래 링크의 영상의 선생님이 아주 설명을 잘해주셔서 이해할 수 있었습니다.

 

https://www.youtube.com/watch?v=BoFqIAywRRg 

 

위 영상에서 일급객체를 비유를 통해서 쉽게 알려주셨는데 

일급객체, 일급함수는

1등 시민이다 -> 시민은 어디든 갈 수 있는권리가 있다. 

    -> 매개변수로 넘어갈 수 있다. -> 함수를 매개변수로 사용.

    -> 리턴타입으로 넘어갈 수 있다. -> 함수를 리턴할 수 있다.

    -> 상수나 변수에 할당할 수 있다. -> 위에서 사용한 클로져 형태 예시.

 

이렇게 보니까 위의 클로져의 기본형태가 왜 저렇게 생겼는지 이해가 가기 시작하는 것 같아요.

Trailing Closure

 

다음은 Trailing Closure(후행 클로져)가 궁금했습니다.

위에 예시를 들었던 것과 같이 함수 타입을 함수의 인자로 사용할 수 있다는 것을 알았죠.

이때 마지막 파라미터가 클로져인 경우 사용하는 클로저입니다.

가독성을 위해서 함수 호출하는 부분의 바깥(중괄호 안)에 작성하는 클로저입니다.

직접 예시를 보는 것이 빠르겠죠?

 

bidding이라는 함수는 int타입의 매개변수 price와 time 을 받고 마지막에 (int, int) -> int 타입의 클로저를 매개변수로 받습니다.

func bidding(price: Int, time: Int, completion: (Int, Int) -> Int) -> Int {
    return completion(a, b)
}

후행 클로저 방식을 사용하지 않고 그대로 bidding함수를 호출해보면 눈에 잘 안들어옵니다.

var result = bidding(price : 10000, time : 15102394234, 
                     completion : { (val1 : Int, val2 : Int) -> Int in
    return price + time
})

후행 클로저 방식을 통해 함수 호출 바깥에 클로저를 작성해줍니다.

 

var result = bidding(price: 10000, time: 161029293393) {(val1 : Int, val2 : Int) -> Int in
    return val1 + val2
}
print(result)

 

 

Escaping Closure

 

다음은 escaping closure입니다.

사실 이부분 때문에 이렇게 클로져를 처음부터 정리해보게 되었습니다.

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

escaping Closures는 한마디로 함수가 끝나고 실행(탈출)되는 클로져입니다.

클로저를 매개변수 중 하나로 사용하는 함수를 선언할 때 @escaping를 앞에 작성하여 클로저가 이스케이프(탈출)할 수 있음을 나타낼 수 있습니다.

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

아래 getData()함수를 예로 들면 

complition의 클로져에 @escaping을 붙여 escaping Clousure라는 것을 명시해주고 있죠.

함수가 끝난 후 실행한다는 의미죠.

 

해당 클로저를 다른 변수에 저장하여 함수가 끝난 후 비동기로 실행할 때 사용하게 되며

예시와 같이 비동기적인 코드를 수행할 때 사용을 하게 됩니다.

 

func getData(completion : @escaping ((Bool) -> Void)){
    let task = URLSession.shared.dataTask(with: URL(string : "")!) {
    data, response, error in 
        guard data != nil else {
            complition(false)
            return
        }
        complition(true)
    }
    task.resume()
}

 

 

참고)

 

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

 

Closures — The Swift Programming Language (Swift 5.7)

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

 

 

https://duwjdtn11.tistory.com/520

 

[iOS] Completion Handler

Completion Handler 본 문서에는 평소에 공부를 진행하며 한번 정리가 필요하다고 생각했던 Completion Handler 에 대한 내용을 기재한다. Prerequisite Completion Handler 개념은 알면 알수록 어려운 개념이다....

duwjdtn11.tistory.com

 

https://jusung.github.io/Escaping-Closure/

 

[Swift] Escaping 클로저 (@escaping)

정의 Escaping 클로저는 클로저가 함수의 인자로 전달됐을 때, 함수의 실행이 종료된 후 실행되는 클로저 입니다. Non-Escaping 클로저는 이와 반대로 함수의 실행이 종료되기 전에 실행되는 클로저

jusung.github.io

https://www.youtube.com/watch?v=5ePkdcPMZ0M&t=52s 

 

728x90

댓글