Swift
Swift | 클로저 closure
iOSDEv
2024. 2. 7. 11:14
클로저란?
(이름이 없는 함수)
함수의 기능가 완전히 동일하고 형태만 다르다
c#에서 사용했던 람다와 동일
내가 느낀바로는 함수와 클로저의 차이라고 생각한다면 함수는 이름이 있는 코드의 묶음으로 다른 코드가 함수이름으로 호출하여 사용할 수 있지만 클로저는 함수의 이름이 없어도 호출 할 수 있는 형태로 사용된다라고 느꼈다
함수는 타입이다
- 함수를 변수에 할당할 수 있음
- 함수를 호출할 때 함수를 파라미터로 전달할 수 있음
- 함수에서 함수를 반환할 수 있음
클로저의 기본형태

클로저는 변수에 담는 방법

함수에서 클로저 형태 변경 해보기

sum 함수를 클로저 형태로 변경하고 싶다면?

타입 추론에의해 타입이 생략이 가능하다

클로저를 파라미터 안에 넣을 수 있다!
(콜백함수)
= 나중에 다시 호출하기 때문에 콜백함수라고 부름
- 예시1

사후적 정의는 아주 많이 사용하는 경우이다 그래서 다른 언어에서 사용할 때도 람다(클로저)를 많이 사용했었다

- 예시2




클로저를 간소화하기
- 문맥상에서 파라미터와 리턴밸류 타입 추론(Type Inference)
- 싱글 익스프레션인 경우(한줄), 리턴을 안 적어도 됨(Implicit Return)
- 아규먼트 이름을 축약(Shorthand Argements) $0, $1
- 트레일링 클로저 문법: 함수의 마지막 전달 인자(아규먼트)로 클로저 전달되는 경우, 소괄호를 생략 가능(후행클로저문법)
- 후행 클로저 문법
- 함수의 마지막 전달 인자를 클로저 전달되는 경우 소괄호 생략이 가능하다




- 타입추론

- 아규먼트 축약

$0 첫 번째 파라미터
$1 두 번째 파라미터
//예시
let closureType1 = { (param) in
return param % 2 == 0
}
let closureType2 = { $0 % 2 == 0 }
let closureType3 = { (a: Int, b:Int) -> Int in
return a * b
}
let closureType4: (Int, Int) -> Int = { (a, b) in
return a * b
}
//타입을 반드시 명시해줘야한다
let closureType5: (Int, Int) -> Int = { $0 * $1 }
//예시2
//Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false, block: <#T##(Timer) -> Void#>)
//false 반복하지 않는거
//형태가 함수며 미리 구현해둔 클로저
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { (timer) in
print("0.5초뒤에 출력하기")
}
//vc.dismiss(animated: true, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
//화면을 닫는 메서드
vc.dismiss(animated: true) {
print("화면을 닫는 것을 완료했습니다.")
}
//UIView.animate(withDuration: <#T##TimeInterval#>, animations: <#T##() -> Void#>, completion: <#T##((Bool) -> Void)?##((Bool) -> Void)?##(Bool) -> Void#>)
UIView.animate(withDuration: <#T##TimeInterval#>) {
<#code#>
} completion: { (<#Bool#>) in
<#code#>
}
completion / completionHandler
: 보통 콜백함수라고 생각하면 됨
// 아규먼트 레이블을 생략하는 경우
// 와일드 카드 패턴 사용시
func multipleClosure2(first: () -> (), _ second: () -> (), third: () -> ()) {
first()
second()
third()
}
//매개변수위 클릭 후 엔터만 치면 알아서 변경됨
/*
multipleClosure2 {
<#code#>
} _: {
<#code#>
} third: {
<#code#>
}
*/
// 아큐먼트 레이블을 생략하지 못함
//레이블 따위를 생략하지 못해서 그냥 사용해야함
multipleClosure2 {
print("1")
} _: {
print("2")
} third: {
print("3")
}
예전에는 마지막만 후행클로저가 가능했지만 현재는 여러개 함수를 파라미터로 넣어도 편하게 사용할 수 있다
클로저 타입은?
참조 타입
값의 저장은 heap (주소는 stack에 저장)
RC를 통해 메모리 관리


클래스와 동일한 참조타입이기 때문에 이러한 현상이 발생함
escaping
- 함수의 실행이 종료되면 파라미터로 쓰이는 클로저도 제거됨
- @escaping 키워드는 클로저를 제거하지 않고 함수에서 탈출시킴
- 함수 내부에서 사용한 클로저를 외부 변수에 저장
- GCD(비동기 코드 사용)

autoclosure : 자동으로 클로저를 만들어주는 경우
기본적으로 non-escaping 특성을 가지고 있음
- 파라미터가 없는 경우에만 사용

- 사용을 지양해라고함
- 번거로움을 해결해주긴함
- 잘사용하진 않음
- 일반적으로 클로저를 써도 되지만 너무 번거로울 때 사용
인프런 앨런 Swift문법 마스터 스쿨을 듣고 정리하였습니다