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입니다.
사실 이부분 때문에 이렇게 클로져를 처음부터 정리해보게 되었습니다.
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
'IOS' 카테고리의 다른 글
iOS 협업 전 팀원 초대, Certificate, Provisioning profile 생성 및 등록 (0) | 2022.09.16 |
---|---|
애플 개발자 계정을 등록하면서... - 에이젠 (0) | 2022.09.15 |
[외주]협업 전 규칙 정리하기 (Convention) - 에이젠 (0) | 2022.09.13 |
GitLab을 처음 만났을 때 (2) | 2022.09.10 |
[iOS] Coordinator 패턴 - 에이젠 (0) | 2022.08.24 |
댓글