public func sorted(by areInIncreasingOrder: (Element, Element) -> Bool) -> [Element]
//정렬할 이름 배열
let names: [String] = ["wizplan", "eric", "yagom", "jenny"]
names
정렬해보자.func backwards(first: String, second: String) -> Bool {
return first > second
}
//MARK: 매개변수로써의 함수
let reversed: [String] = names.sorted(by: backwards)
//MARK: 매개변수에 클로저 대입
let reversed = names.sorted(by: {(first: String, second: String) -> Bool in
return first > second
})
//MARK: 후행 클로저 사용
let reversed = names.sorted() { (first: String, second: String) -> Bool in
return first > second
}
//MARK: 후행 클로저 사용 - sorted(by:) 메소드의 소괄호까지 생략 가능
let reversed = names.sorted { (first: String, second: String) -> Bool in
return first > second
}
func doSomething(do: (String) -> Void,
onSuccess: (Any) -> Void,
onFailure: (Error) -> Void) {
// do something...
}
//MARK: 다중 후행 클로저의 사용
doSomething { (something: String) in
//do closure
} onSuccess: { (result: Any) in
//success closure
} onFailure: { (error: Error) in
//failure closure
}
//MARK: 문맥 타입유추
let reversed = names.sorted { (first, second) -> Bool in
return first > second
}
//MARK: 단축인자 사용
let reversed = names.sorted {
return $0 > $1
}
//MARK: 암시적 반환 표현
let reversed = names.sorted {
$0 > $1
}
//MARK: 클로저로서의 연산자 함수 사용
let reversed = names.sorted(by: >)
func makeIncrementer(forIncrement amount: Int) -> (() -> Int) {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let incrementByTwo: (() -> Int) = makeIncrementer(forIncrement: 2)
let first: Int = incrementByTwo()
let second: Int = incrementByTwo()
let thrid: Int = incrementByTwo()
print(first)
print(second)
print(thrid)
---result---
2
4
6
💡 클래스 인스턴스 프로퍼티로서의 클로저
클래스 인스턴스의 프로퍼티로 클로저를 할당한다면 클로저는 해당 인스턴스 또는 인스턴스의 멤버의 참조를 획득할 수 있으나, 클로저와 인스턴스 사이에 강한참조 순환 문제가 발생할 수 있다.
incrementByTwo
는 runningTotal 값 획득을 통해 계속해서 증가시킬 수 있었다.탈출(Escape)
한다고 표현한다.@escaping
키워드를 사용하여 클로저가 탈출하는 것을 허용한다고 명시해줄 수 있다.typealias VoidVoidClosure = () -> ()
let firstClosure: VoidVoidClosure = {
print("Closure A")
}
let secondClosure: VoidVoidClosure = {
print("Closure B")
}
//first, second 매개변수 클로전느 함수의 반환 값으로 사용될 수 있으므로 탈출 클로저.
func returnOneClosure(first: @escaping VoidVoidClosure, second: @escaping VoidVoidClosure, shouldReturnFirstClosure: Bool) -> VoidVoidClosure {
return shouldReturnFirstClosure ? first : second
}
//함수에서 반환한 클로저가 함수 외부의 상수에 저장됨.
let returnedClosure: VoidVoidClosure = returnOneClosure(first: firstClosure, second: secondClosure, shouldReturnFirstClosure: true)
returnedClosure()
var closures: [VoidVoidClosure] = []
//closure 매개변수 클로저는 함수 외부의 변수에 저장될 수 있으므로 탈출 클로저.
func appendClosure(closure: @escaping VoidVoidClosure) {
closures.append(closure)
}
self
키워드를 명시적으로 사용해야 한다.func functionWithNoescapeClosure(closure: VoidVoidClosure) {
closure()
}
func functionWithEscapingClosure(completionHandler: @escaping VoidVoidClosure) -> VoidVoidClosure {
return completionHandler
}
class SomeClass {
var x = 10
func runNoescapeClosure() {
functionWithNoescapeClosure { x = 200}
}
func runEscapingClosure() -> VoidVoidCLosure {
return functionWithEscapingClosure { self.x = 100}
}
}
let instance = SomeClass()
instance.runNoescapeClosure()
print(instance.x) // 200
let returnedClosure: VoidVoidClosure = instance.runEscapingClosure()
returnedClosure()
print(instance.x) // 100