티스토리 뷰
https://github.com/JeaSungLEE/iOSInterviewquestions
GitHub - JeaSungLEE/iOSInterviewquestions: 👨🏻💻👩🏻💻iOS 면접에 나올 질문들 총 정리
👨🏻💻👩🏻💻iOS 면접에 나올 질문들 총 정리 . Contribute to JeaSungLEE/iOSInterviewquestions development by creating an account on GitHub.
github.com
Swift에서 클로저(Closure)란 무엇이며, 어떻게 사용하나요?
- 클로저의 캡처(Capture) 기능은 무엇인가요?
- @escaping 클로저와 non-escaping 클로저의 차이점은 무엇인가요?
- 트레일링 클로저(Trailing Closure) 문법은 어떤 경우에 유용한가요?
클로저(Closure)
클로저란 코드에 전달되어 사용할 수 있는 독립적인 기능 블록이라고 정의되어있습니다.
다른 언어의 클로저, 익명 함수, 람다, 블록과 유사하다고 합니다.
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
// 가장 일반적인 클로저의 사용
let reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
// 1. 타입 추론을 통한 생략
let reversedNames1 = names.sorted(by: { s1, s2 in
return s1 > s2
})
// 2. 단일 표현식의 암시적 반환
let reversedNames2 = names.sorted(by: { s1, s2 in
s1 > s2
})
// 3. 전달 인자의 자동 참조
let reversedNames3 = names.sorted(by: { $0 > $1 })
// 4. 후행 클로저 사용
let reversedNames4 = names.sorted { $0 > $1 }
// 5. 연산자 메서드 사용
let reversedNames5 = names.sorted(by: >)
- 위처럼 클로저의 경우 함축적인 표현이 가능한데, 이러한 함축적인 표현은 코드를 보는 개발자에게 혼동을 줄 수 있기 때문에 적절히 사용하는 것이 중요하다.
클로저의 캡처(Capture) 기능
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen() // 10
incrementByTen() // 20
incrementByTen() // 30
let incrementByFive = makeIncrementer(forIncrement: 5)
incrementByFive() // 5
incrementByTen() // 40
incrementByFive() // 10
incrementByTen을 생성할때 runningTotal은 0으로 초기화가 되고 이후 incrementer는 해당 값을 기억(Capture)해 두고 실행이 될때 마다 해당 값을 증가시킵니다. 이때 incrementByFive와 Ten은 서로 캡처해둔 runningTotal이 다르기 때문에 서로의 값에는 영향을 주지 않습니다.
Escaping Closure
클로저가 함수에 인수로 전달되지만 함수가 반환된 이후 호출 될때, 이스케이프(탈출)한다고 합니다. 이 경우 전달할때 @escaping 키워드를 붙여 이스케이프 될 수 있음을 나타내야합니다.
var completionHandlers: [() -> Void] = []
// escaping 클로저
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
// non-escaping 클로저
func someFunctionWithNonescapingClosure(closure: () -> Void) {
closure()
}
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 } // { [self] in x = 100 }과 같음
someFunctionWithNonescapingClosure { x = 200 }
}
}
let instance = SomeClass()
instance.doSomething()
// non-escaping 클로저 - doSomething 내부에서 실행
print(instance.x) // 200
// escaping 클로저 - doSomething 외부에서 실행
completionHandlers.first?()
print(instance.x) // 100
트레일링 클로저(Trailing Closure) - 후행클로저
Closure의 4번 항목처럼 클로저가 함수의 마지막 인자일 때, 소괄호 밖으로 빼서 사용하는 방법입니다.
If you need to pass a closure expression to a function as the function’s final argument and the closure expression is long, it can be useful to write it as a trailing closure instead.
문서에서는 클로저가 너무 길어서 한 줄에 인라인으로 작성할 수 없을때 가장 유용하다고 나옵니다. 또한 클로저 내부에 다른 클로저가 존재할 경우에도 구분하기가 편해 유용합니다.
참고자료
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/
Documentation
docs.swift.org
'프로그래밍 > 기초' 카테고리의 다른 글
| [Lv1 - 13] 고차함수(Higher Order Functions) (0) | 2025.07.21 |
|---|---|
| 함수와 클로저의 차이점 (0) | 2025.07.08 |
| CPU, RAM, 저장 장치의 역할과 상호 작용 (0) | 2025.07.01 |
| 클린아키텍처(Clean Architecture) (2) | 2025.05.25 |
| 메모리구조, ARC (with GC, 약한 참조, 미소유 참조) (0) | 2025.02.10 |
