ํด๋ก์ (Closures)
- ์ ์ญํจ์ = ์ด๋ฆ์ ๊ฐ์ง๊ณ ์ด๋ ํ ๊ฐ๋ ์บก์ฒํ์ง ์๋ ํด๋ก์
- ์ค์ฒฉ ํจ์ = ์ด๋ฆ์ ๊ฐ์ง๊ณ ๋๋ฌ์ผ ํจ์๋ก ๋ถํฐ ๊ฐ์ ์บก์ฒํ ์ ์๋ ํด๋ก์
- ์ฃผ๋ณ ์ปจํ ์คํธ์์ ๊ฐ์ ์บก์ฒํ ์ ์๋ ์์ฝ๋ ๊ตฌ๋ฌธ = ์ด๋ฆ์ด ์๋ ํด๋ก์ (Unnamed Closure)
- ํด๋ก์ ์ ํ๋ผ๋ฏธํฐ → inout ํ๋ผ๋ฏธํฐ ์ผ ์ ์์ง๋ง ๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ง ์ ์๋ค.
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backward(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversedNames = names.sorted(by: backward)
// backwardํจ์๋ฅผ ํด๋ก์ ๋ก ํํ
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
// ์งง์ผ๋ฉด ํ ์ค๋ก ํํ
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
// ํ์
์ถ๋ก -> ๋ฆฌํด ํ์
๊ณผ ํ๋ผ๋ฏธํฐ ํ์
์๋ต
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
// return ํค์๋ ์๋ต
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
// Shorthand Argument Names ์ฌ์ฉ
reversedNames = names.sorted(by: { $0 > $1 } )
// Operator ๋ฉ์๋
reversedNames = names.sorted(by: >)
ํํ ํด๋ก์ (Trailing Closures)
- ํจ์์ ๋ง์ง๋ง argument๋ก ํด๋ก์ ๋ฅผ ์ ๋ฌํ ๋ ํํ ํด๋ก์ ๋ก ์์ฑ
func loadPicture(from server: Server, completion: (Picture) -> Void, onFailure: () -> Void) {
if let picture = download("photo.jpg", from: server) {
completion(picture)
} else {
onFailure()
}
}
loadPicture(from: someServer) { picture in
someView.currentPicture = picture
} onFailure: {
print("Couldn't download the next picture.")
}
- 2๊ฐ์ ํด๋ก์ ๋ฅผ ์ฌ์ฉ
- ๋คํธ์ํฌ ํต์ ์ด ์ฑ๊ณตํ ๊ฒฝ์ฐ์์ ๋คํธ์ํฌ ์ค๋ฅ ์ฒ๋ฆฌ ์ฝ๋ ๋ถ๋ฆฌํ ์ ์๋ค.
์บก์ฒ๊ฐ (Capturing Values)
- ํด๋ก์ ์บก์ณ๋ ํด๋ก์ ๊ฐ ๋งค๊ฐ๋ณ์๋ ์ง์ญ๋ณ์๊ฐ ์๋ ์ฃผ๋ณ ์ธ๋ถ์ context๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ฃผ๋ณ ์ธ๋ถ์ context๋ฅผ ์ฐธ์กฐํ๋ ๊ฒ(Capturing by reference)
- ์ปจํ ์คํธ์์ ์์์ ๋ณ์๋ฅผ ์บก์ฒ (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()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
// returns a value of 30
- ์ค์ฒฉํจ์ & ๋ฆฌํด ํ์ = () -> Int → ํจ์ ๋ฐํํ๋ค๋ ์๋ฏธ
- incrementer() ํจ์๋ runningTotal ๊ณผ amount 2๊ฐ์ ๊ฐ์ ์บก์ฒ
- incrementByTen์ด ์ด ๋์ ์บก์ณ → ๊ฐ์ด ๊ณ์ ์ด์์๊ฒ ๋๊ณ , ๋ฐ๋ผ์ ์ด ํด๋ก์ ๋ฅผ ํธ์ถํจ์ ๋ฐ๋ผ ๊ฐ์ด updating์ด ๋จ
ํด๋ก์ ๋ ์ฐธ์กฐ ํ์
let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
// returns a value of 40
- 2๊ฐ ๋ชจ๋ ๊ฐ์ ํด๋ก์ ๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ๋๋ค ์ฆ๊ฐ
- ํด๋ก์ ์ reference count๊ฐ 0์ด ๋์ง ์๋ ํ ์บก์ณํ runningTotal์ด๋ amount๋ ์ฌ๋ผ์ง์ง ์๋๋ค.
ํ์ถ ํด๋ก์ (Escaping Closures)
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
// ํจ์ ๋ฐ๊นฅ์ ์ ์ธ๋ ๋ฐฐ์ด์ ์ถ๊ฐ -> @escaping ํ์ ํด์ผ ํจ(์ํ๋ฉด ์ปดํ์ผ ์๋ฌ)
completionHandlers.append(completionHandler)
}
- @escaping
- ํด๋ก์ ๊ฐ ํ์ถ → ํจ์ ๋ฐ๊นฅ์ ์ ์๋ ๋ณ์์ ์ ์ฅ๋๋ ๊ฒ
- self ์บก์ณ → ๊ฐํ ์ฐธ์กฐ ์ํ์ด ์๊ธธ ์ ์์
class Class2 {
var handler: ((Int) -> Void)? = nil
func format(_ value: Int) -> String { return String(value) }
func test() {
handler = { [weak self] value in
let formatted = self?.format(value)
print("formatted: \\(formatted as Any)")
}
}
deinit {
print("Class2 deinit")
}
}
- ํจ์ ์ธ๋ถ ๋ณ์์ escaping ํด๋ก์ ๊ฐ ์ ์ฅ๋ ๋๋ [weak self]๋ฅผ ์ฌ์ฉํ์
'Swift Language Guide' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift Language Guide] ๊ตฌ์กฐ์ฒด์ ํด๋์ค (Structures and Classes) (0) | 2023.06.05 |
---|---|
[Swift Language Guide] ์ด๊ฑฐํ (Enumerations) (0) | 2023.06.05 |
[Swift Language Guide] ํจ์(Functions) (0) | 2023.05.24 |
[Swift Language Guide] ์ ์ดํ๋ฆ(Control Flow) (0) | 2023.05.24 |
[Swift Language Guide] ์ฝ๋ ์ ํ์ (Collection Types) (0) | 2023.05.24 |