클로저는 코드에서 주변에 전달과 함께 사용할 수 있는 자체 포함형 기능 블럭이다. 클로저는 정의된 컨텍스트에서 모든 상수와 변수에 대한 참조를 캡처 및 저장 가능하다. 이러한 상수와 변수를 폐쇄(closing over)라고 한다.
{ (Parameters) -> return type in
statements
}
func backword(_ s1 : String, _ s2 : String) {
return s1 > s2
}
var reversedName = name.sorted(by: backward)
//다음과 같을 경우 정상적으로 재배열이 일어난다.
//다음 예시는 sorted(by:) 메서드 파라미터에 필요한 함수타입을 만족하는 함수를 정의하고 이를 대입시켜준 것이다
reversedName = names.sorted(by: {(s1 : String, s2 : String) -> Bool in
return s1 > s2
})
//다음은 위 함수의 클로저 표현이다.
reversedName = names.sorted(by: {s1, s2 in return s1 > s2})
//다음과 같은 경우 타입 유추가 일어나며 별도의 파라미터에 대한 타입을 명시하지 않아도 코드가 실행된다.
reversedName = names.sorted(by: { s1, s2 in s1 > s2 } )
//단일 표현 클로저에 대한 암시적 반환의 예시이다.
//sorted메서드의 인자 함수타입은 클로저에서 Bool 값을 반환해야 하므로 명확하다.
//따라서 모호하지 않으므로 return 또한 생략 가능하다.
reversedName = names.sorted(by: {$0 > $1})
//여기에서 $0, $1은 클로저의 첫째 둘째 String 인자를 참조한다.
//$1이 짧은 인자에서 가장 높은 숫자이기 때문에 클로저는 2개의 인자가 있다고 이해한다.
//sorted(by:) 함수는 인자가 모두 문자열인 클로저를 기대하기 때문에 자동으로 String타입으로 유추를 한다.
가장 핵심이 되는 개념 분야이다. 후행 클로저는 함수의 마지막 인자로 함수에 클로저 표현식을 전달해야 하고 클로저 표현식이 긴 경우 사용한다. 후행 클로저는 함수의 인자지만 함수 호출의 소괄호 다음에 작성한다. 후행 클로저 구문을 사용할 때는 함수 호출의 일부로 첫 클로저 인자 라벨을 작성하지 않아도 된다.
func someFunction(closure : () -> Void) {
print("a")
closure()
}
//다음과 같은 경우 a 출력 후 클로저가 실행된다.
someFunction(closure: {
//여기에 클로저를 통해 수행할 함수의 바디가 들어간다.
})
someFunction() {
print("b)
}
//다음과 같이 클로저 표현구와 더불어 함수를 호출하게 되면,
//1차적으로 someFunction이 호출되면서 a를 출력하고, 그 후 후행클로저 실행으로 b가 출력된다.
reversedName = names.sorted() { $0 > $1 }
//다음과 같은 경우 후행 클로저로 표현식이 함수와 메서드의 유일한 인자인 경우 뒤에 소괄호를 생략하고
//아래 예시와 같이 작성이 가능하다.
reversedName = names.sorted {$0 > $1}
//다음과 같이 간단하게 작성 가능하다.
func loadPicture(from server : Server, completion: (Picture) -> Void, onFailure : () -> Void) {
if let picture. = download("photo.jpg", from : server) {
completion(picture)
} else {
onFailure()
}
}
//다음의 함수는 2개의 클로저를 제공한다. 첫째는 사진 다운로드 후 완료처리 클로저이며,
//둘째는 오류를 표시하는 오류처리 클로저이다.
loadPicture(from : someServer) { picture in
someView.currentPicture = picture // 1차 후행클로저 수행
} onFailure: {
print("Failed to save image")
} // 2차 후행 클로저를 수행