[Swift] Closure(클로저) 2/3

어흥·2024년 5월 29일

Swift

목록 보기
16/28

안녕하세요 클로저 2편입니다!!! 오늘은 문법 최적화와 클로저에 많이 사용되는 attribute keyword에 대해서 알아보겠습니다.
클로저에 대해서 잘 모르신다면 1편을 보고 오시는걸 추천합니다.

클로저의 문법 최적화

swift는 클로저 문법에 대해서 간편화할 수 있는 방법을 많이 제공하고 있습니다. 오늘은 클로저를 어떻게 간편화할 수 있는지 알아볼게용

후행(trailing) 클로저

후행 클로저는 함수의 마지막 전달 인자(아규먼트)로 클로저 전달되는 경우, 소괄호를 생략 가능한 클로저를 말합니다.

예를 들어보겠습니다. 아래와 같이 클로저를 파라미터로 포함하는 함수가 있습니다.

func closureParamFunction(closure: () -> Void){ // 정의
	print("function start")
    closure()
}

배운대로면 아래와 같이 쓰는게 맞습니다. 하지만 중괄호를 감싸는 소괄호 형태는 조금 불편합니다. (저도 중괄호 작성하고 소괄호를 항상 까먹었죠.. ㅎ)

  • 원래 함수 실행문
closureParamFunction(closure: { // 함수 실행문 
	print("closure start")
})

func closureCaseFunction(a: Int, b: Int, closure: (Int) -> Void) {
    let c = a + b
    closure(c)
}
  • 간편화된 함수 실행문
closureParamFunction(closure: ) {      // 소괄호를 앞으로 가져오기
    print("프린트 종료")
}

closureParamFunction() {               // 아규먼트 생략가능
    print("프린트 종료")
}


closureParamFunction {                 // 소괄호 생략 가능 
    print("프린트 종료")
}

closureCaseFunction(a: 5, b: 2) { number in      
    print("출력할까요? \(number)")
}

보통 소괄호를 생략한 클로저 형태를 주로 사용하니 잘 익혀두실 필요가 있습니다.

파라미터, 리턴값 간소화

func performClosure(param: (String, String) -> Int) { 
    param("Swift", "closure")
}

리턴 생략(Implicit Return)

single expression(한줄)인 경우 return을 적지 않아도 됩니다.

performClosure(param: { str in
    str.count
})

argument 이름 축약

argument 이름을 축약해서 사용할 수 있습니다. 각각의 argument를 $0, $1... 형태로 축약하여 사용할 수 있습니다.

performClosure(param: {
    $0.count + $1.count
})
  • 원칙적으로 함수의 실행이 종료되면 파라미터로 쓰이는 클로저도 제거됨
  • @escaping 키워드는 클로저를 제거하지 않고 함수에서 탈출시킴(함수가 종료되어도 클로저가 존재하도록 함)
  • ==> 클로저가 함수의 실행흐름(스택프레임)을 벗어날 수 있도록 함

@escaping

함수의 파라미터로 사용되는 클로저는 원칙적으로 함수의 실행이 종료되면 클로저도 제거되는게 당연합니다. @escaping 키워드는 클로저를 제거하지 않고 함수의 스택 프레임을 벗어날 수 있게하는 키워입니다.

@escaping 사용의 대표적인 경우

  • 1) 어떤 함수의 내부에 존재하는 클로저(함수)를 외부 변수에 저장
  • 2) GCD (비동기 코드의 사용)
var aSavedFunction: () -> () = { print("출력") }
aSavedFunction()


func performEscaping2(closure: @escaping () -> ()) {
    aSavedFunction = closure         
}

0개의 댓글