μλ νμΈμ. μ΄λ² ν¬μ€νΈμμλ ν΄λ‘μ (Closures)μ λν΄ μμλ³΄κ² μ΅λλ€.
π ν΄λ‘μ λ?
ν΄λ‘μ λ μ½λμμ μ λ¬νκ³ μ¬μ©ν μ μλ μ체 ν¬ν¨λ κΈ°λ₯ λΈλ‘μ λλ€. Cλ Objective-Cμ λΈλ‘(blocks), λ€λ₯Έ μΈμ΄μ λλ€(lambdas)μ μ μ¬ν κ°λ μ λλ€.
ν΄λ‘μ (Closure): λ 립μ μΈ μ½λ λΈλ‘μΌλ‘, ν¨μμ²λΌ μλνμ§λ§ μ΄λ¦μ΄ μμ μλ μμΌλ©° μ£Όλ³ μ»¨ν μ€νΈμ κ°μ μΊ‘μ²ν μ μμ΅λλ€.
Swiftμμ ν΄λ‘μ λ μΈ κ°μ§ ννλ‘ λνλ©λλ€:
- μ μ ν¨μ: μ΄λ¦μ΄ μκ³ μ΄λ€ κ°λ μΊ‘μ²νμ§ μλ ν΄λ‘μ
- μ€μ²© ν¨μ: μ΄λ¦μ΄ μκ³ λλ¬μΌ ν¨μμμ κ°μ μΊ‘μ²ν μ μλ ν΄λ‘μ
- ν΄λ‘μ ννμ: μ΄λ¦μ΄ μκ³ μ£Όλ³ μ»¨ν μ€νΈμμ κ°μ μΊ‘μ²ν μ μλ κ²½λ ꡬ문
π ν΄λ‘μ ννμ ꡬ문
ν΄λ‘μ ννμμ κ°κ²°ν μΈλΌμΈ ꡬ문μΌλ‘ ν΄λ‘μ λ₯Ό μμ±νλ λ°©λ²μ λλ€. κΈ°λ³Έ ꡬ문μ λ€μκ³Ό κ°μ΅λλ€:
{ (parameters) -> ReturnType in
statements
}
μ΄ κ°λ μ μ€λͺ νκΈ° μν΄ λ°°μ΄ μ λ ¬ μμ λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€:
// μ λ ¬ν λ°°μ΄
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
// μΌλ° ν¨μλ₯Ό μ¬μ©ν μ λ ¬
func backward(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversedNames = names.sorted(by: backward)
// ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
// ν΄λ‘μ ννμμ μ¬μ©ν μ λ ¬
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
sorted(by:): λ°°μ΄μ μμλ₯Ό μ λ ¬νλ λ©μλλ‘, μ λ ¬ κΈ°μ€μ μ μνλ ν΄λ‘μ λ₯Ό μΈμλ‘ λ°μ΅λλ€.
π ν΄λ‘μ μ΅μ ν κΈ°λ²
Swiftλ ν΄λ‘μ μ½λλ₯Ό λ κ°κ²°νκ² μμ±ν μ μλ μ¬λ¬ μ΅μ ν κΈ°λ²μ μ 곡ν©λλ€:
1. νμ μΆλ‘
컨ν μ€νΈμμ νμ μ μ μΆν μ μμ λλ νμ λͺ μλ₯Ό μλ΅ν μ μμ΅λλ€:
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 })
νμ μΆλ‘ (Type Inference): Swiftκ° μ½λμ 컨ν μ€νΈλ₯Ό κΈ°λ°μΌλ‘ λ³μλ μμμ νμ μ μλμΌλ‘ κ²°μ νλ κΈ°λ₯
2. λ¨μΌ ννμμ μμμ λ°ν
ν΄λ‘μ κ° λ¨μΌ ννμλ§ ν¬ν¨νλ κ²½μ° return ν€μλλ₯Ό μλ΅ν μ μμ΅λλ€:
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 })
3. μΆμ½ μΈμ μ΄λ¦
μΈλΌμΈ ν΄λ‘μ μμλ $0, $1, $2 λ±κ³Ό κ°μ μΆμ½ μΈμ μ΄λ¦μ μ¬μ©ν μ μμ΅λλ€:
reversedNames = names.sorted(by: { $0 > $1 })
μΆμ½ μΈμ μ΄λ¦(Shorthand Argument Names): ν΄λ‘μ μμ μλμΌλ‘ μ 곡λλ $0, $1 λ±μ νλΌλ―Έν° μ΄λ¦μΌλ‘, κ°κ° 첫 λ²μ§Έ, λ λ²μ§Έ μΈμλ₯Ό λνλ λλ€.
4. μ°μ°μ λ©μλ
λΉκ΅ μ°μ°μλ κ·Έ μμ²΄λ‘ (String, String) -> Bool νμ μ ν¨μμ΄λ―λ‘ μ§μ μ¬μ©ν μ μμ΅λλ€:
reversedNames = names.sorted(by: >)
π νν ν΄λ‘μ (Trailing Closures)
ν¨μμ λ§μ§λ§ μΈμκ° ν΄λ‘μ μΌ λ, ν¨μ νΈμΆ κ΄νΈ λ€μ ν΄λ‘μ λ₯Ό μμ±νλ λ¬Έλ²μ λλ€:
// νν ν΄λ‘μ ꡬ문
reversedNames = names.sorted() { $0 > $1 }
// ν΄λ‘μ κ° μ μΌν μΈμλΌλ©΄ κ΄νΈλ μλ΅ κ°λ₯
reversedNames = names.sorted { $0 > $1 }
νν ν΄λ‘μ (Trailing Closure): ν¨μ νΈμΆ μ λ§μ§λ§ μΈμκ° ν΄λ‘μ μΈ κ²½μ°, κ΄νΈ λ°μ ν΄λ‘μ λ₯Ό μμ±ν μ μλ λ¬Έλ²
νν ν΄λ‘μ λ ν΄λ‘μ κ° κΈΈκ±°λ 볡μ‘ν λ νΉν μ μ©ν©λλ€:
let numbers = [16, 58, 510]
let strings = numbers.map { (number) -> String in
var number = number
var output = ""
// 볡μ‘ν λ³ν λ‘μ§...
return output
}
μ¬λ¬ ν΄λ‘μ κ° μλ ν¨μμ κ²½μ°:
func loadPicture(from server: Server,
completion: (Picture) -> Void,
onFailure: () -> Void) {
// ν¨μ ꡬν...
}
// μ¬λ¬ νν ν΄λ‘μ μ¬μ©
loadPicture(from: someServer) { picture in
someView.currentPicture = picture
} onFailure: {
print("μ¬μ§μ λ€μ΄λ‘λν μ μμ΅λλ€.")
}
π κ° μΊ‘μ² (Capturing Values)
ν΄λ‘μ λ μ μλ 컨ν μ€νΈμ μμμ λ³μλ₯Ό μΊ‘μ²νμ¬ λμ€μ μ¬μ©ν μ μμ΅λλ€. μ΄κ²μ ν΄λ‘μ κ° μμ±λ νκ²½μ κ°μ "κΈ°μ΅"ν μ μκ² ν΄μ€λλ€:
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
κ° μΊ‘μ²(Capturing Values): ν΄λ‘μ κ° μμ μ΄ μ μλ νκ²½μ λ³μλ μμλ₯Ό μ°Έμ‘°νμ¬ μ μ₯νλ κ²
μ΄ μμ μμ incrementer ν¨μλ runningTotalκ³Ό amount λ³μλ₯Ό μΊ‘μ²νμ¬, makeIncrementer ν¨μκ° λ°νλ νμλ μ΄ κ°λ€μ κΈ°μ΅νκ³ μ¬μ©ν μ μμ΅λλ€.
π ν΄λ‘μ λ μ°Έμ‘° νμ (Closures Are Reference Types)
ν¨μμ ν΄λ‘μ λ μ°Έμ‘° νμ μ λλ€. μ¦, ν΄λ‘μ λ₯Ό λ³μλ μμμ ν λΉν λ μ€μ λ‘λ ν΄λ‘μ μ λν μ°Έμ‘°κ° ν λΉλ©λλ€:
let alsoIncrementByTen = incrementByTen
alsoIncrementByTen() // 40
incrementByTen() // 50
μ°Έμ‘° νμ (Reference Type): μΈμ€ν΄μ€κ° 볡μ¬λλ λμ μ°Έμ‘°λ‘ μ λ¬λλ νμ . κ°μ ν΄λ‘μ λ₯Ό μ°Έμ‘°νλ μ¬λ¬ λ³μλ κ°μ ν΄λ‘μ μΈμ€ν΄μ€λ₯Ό κ°λ¦¬ν΅λλ€.
π νμΆ ν΄λ‘μ (Escaping Closures)
ν΄λ‘μ κ° ν¨μμ μΈμλ‘ μ λ¬λμμ§λ§ ν¨μκ° λ°νλ νμλ νΈμΆλ μ μλ€λ©΄ μ΄λ₯Ό "νμΆ ν΄λ‘μ "λΌκ³ ν©λλ€:
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
νμΆ ν΄λ‘μ (@escaping): ν¨μκ° λ°νλ νμλ μ€νλ μ μλ ν΄λ‘μ . ν¨μ μΈλΆ λ³μμ μ μ₯λκ±°λ λΉλκΈ° μμ μ μ¬μ©λ λ νν νμν©λλ€.
νμΆ ν΄λ‘μ μμ selfλ₯Ό μ°Έμ‘°ν λλ νΉλ³ν μ£Όμκ° νμν©λλ€:
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 } // self λͺ
μμ μ¬μ©
someFunctionWithNonescapingClosure { x = 200 } // self μμμ μ¬μ© κ°λ₯
}
}
Swift 5.3λΆν°λ ν΄λ‘μ μΊ‘μ² λͺ©λ‘μ μ¬μ©ν΄ selfλ₯Ό μΊ‘μ²ν μλ μμ΅λλ€:
someFunctionWithEscapingClosure { [self] in x = 100 }
π μλ ν΄λ‘μ (Autoclosures)
μλ ν΄λ‘μ λ ν¨μμ μΈμλ‘ μ λ¬λλ ννμμ μλμΌλ‘ ν΄λ‘μ λ‘ κ°μΈλ κΈ°λ₯μ λλ€:
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
// μΌλ° ν΄λ‘μ
func serve(customer customerProvider: () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) })
// μλ ν΄λ‘μ
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0)) // ν΄λ‘μ ꡬ문 μμ΄ ννμλ§ μ λ¬
μλ ν΄λ‘μ (@autoclosure): μΈμλ‘ μ λ¬λ ννμμ μλμΌλ‘ ν΄λ‘μ λ‘ λννλ μμ±. μ½λλ₯Ό λ κ°κ²°νκ² λ§λ€μ§λ§, λ¨μ©νλ©΄ κ°λ μ±μ΄ λ¨μ΄μ§ μ μμ΅λλ€.
μλ ν΄λ‘μ μ κ°μ₯ ν° νΉμ§μ μ½λ μ€νμ μ§μ°μν¨λ€λ μ μ λλ€. ν΄λ‘μ κ° μ€μ λ‘ νΈμΆλ λκΉμ§ λ΄λΆ μ½λλ μ€νλμ§ μμ΅λλ€.
νμΆμ΄ νμν μλ ν΄λ‘μ λ @autoclosureμ @escaping μμ±μ λͺ¨λ μ¬μ©ν©λλ€:
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
// ꡬν...
}
μ΄μμΌλ‘ Swiftμ ν΄λ‘μ μ λν μ€λͺ μ λ§μΉκ² μ΅λλ€.
'π₯ Bread Basics > Swift' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Swift 곡μ λ¬Έμ μ 리 - λ©μλ (Methods) (0) | 2025.04.11 |
---|---|
Swift 곡μ λ¬Έμ μ 리 - νλ‘νΌν° (Properties) (0) | 2025.04.11 |
Swift 곡μ λ¬Έμ μ 리 - ꡬ쑰체μ ν΄λμ€ (Structures and Classes) (0) | 2025.04.11 |
Swift 곡μ λ¬Έμ μ 리 - μ΄κ±°ν (Enumerations) (0) | 2025.04.11 |
Swift 곡μ λ¬Έμ μ 리 - ν¨μ (Functions) (0) | 2025.04.11 |
Swift 곡μ λ¬Έμ μ 리 - μ μ΄ νλ¦ (Control Flow) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - 컬λ μ νμ (Collection Types) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - λ¬Έμμ΄κ³Ό λ¬Έμ (Strings and Characters) (0) | 2025.04.10 |