TIL: 클로저를 사용하는 이유

Royce·2025년 3월 29일

Swift 문법

목록 보기
59/63

클로저를 사용하는 이유

클로저는 왜 사용하는가?

  • 클로저는 함수처럼 동작하지만, 정의와 전달이 유연하다는 장점이 있다
  • 주로 함수의 파라미터로 전달하거나 간단한 동작을 즉시 정의할 때 사용한다
  • 함수의 흐름 중 특정 시점에 실행할 동작을 외부에서 주입할 수 있어 활용도가 높다

클로저에 이름이 필요 없는 이유

  • 클로저는 대부분 일회성 작업이나 간단한 동작을 정의할 때 사용된다
  • 이름을 붙이지 않아도 되므로 코드가 간결하고 직관적으로 작성될 수 있다
  • 특히 클로저를 파라미터로 직접 전달할 때는 이름 없는 형태가 더 자연스럽다
  • 복잡한 로직이 없는 짧은 작업에는 이름 없이 사용하는 것이 일반적이다

콜백 함수란?

  • 콜백 함수(Callback Function)는 특정 작업이 완료된 후 호출되는 함수를 의미한다
  • 주로 비동기 작업이나 이벤트 처리에서 사용된다
  • 어떤 함수가 실행을 마친 후, 결과나 후속 작업을 처리하기 위해 콜백 함수를 실행한다
  • Swift에서는 클로저를 통해 콜백 함수를 표현하는 경우가 많다
  • 즉, 콜백 함수는 나중에 실행될 함수를 미리 정의해두고, 필요한 시점에 실행하는 개념이다

클로저 예제 - 콜백 함수로 사용

// 데이터를 다운로드하는 함수 (비동기 작업 시뮬레이션)
func downloadData(completion: (String) -> Void) {
    print("데이터 다운로드 중")
    let data = "다운로드된 데이터"
    completion(data)  // 데이터를 클로저로 전달하여 호출
}

// 클로저를 전달하여 다운로드 완료 후 동작을 정의

downloadData { result in
    print("다운로드 완료: \(result)")
}
  • downloadData 함수는 데이터를 다운로드하고, 완료되면 전달된 클로저(completion)를 호출하여 결과를 전달한다
  • 클로저는 데이터를 받은 후 그 값을 출력하는 방식으로 사용된다

클로저를 파라미터로 전달하는 예시

func runTask(task: () -> Void) {
    print("작업 시작")
    task()  // 전달받은 클로저 실행
    print("작업 끝")
}

let uploadTask = {
    print("업로드 중")
}

runTask(task: uploadTask)  // 미리 정의된 클로저 전달하여 실행

runTask {
    print("파일을 저장 중")  // 후행 클로저 방식
}
  • runTask 함수는 전달된 클로저를 호출하여 작업 중간 동작을 실행한다
  • 클로저는 사전에 정의하거나 후행 클로저 형태로 직접 전달할 수 있다

클로저로 결과값 전달받기

func calculate(a: Int, b: Int, completion: (Int) -> Void) {
    let result = a + b
    completion(result)  // 결과를 클로저로 전달
}

calculate(a: 5, b: 3) { result in
    print("계산 결과: \(result)")
}

let printResult: (Int) -> Void = { value in
    print("결과 값은 \(value) 입니다")
}

calculate(a: 10, b: 20, completion: printResult)
  • calculate 함수는 두 수를 더한 결과를 클로저로 전달한다
  • 클로저를 이용하여 외부에서 결과값을 유연하게 처리할 수 있다

여러 클로저 전달 예제

func performActions(start: () -> Void, finish: () -> Void) {
    start()  // 시작 클로저 실행
    print("진행 중")
    finish()  // 종료 클로저 실행
}

performActions(start: {
    print("준비 시작")
}, finish: {
    print("작업 완료")
})
  • performActions 함수는 여러 클로저를 전달받아 실행 흐름을 제어한다

클로저를 왜 사용하는가? (다양한 방식)

func closureParamFunction(closure: () -> ()) {
    print("프린트 시작")
    closure()  // 전달받은 클로저 실행
}

func printSwiftFunction() {
    print("프린트 종료")
}

let printSwift = { () -> () in
    print("프린트 종료")
}

closureParamFunction(closure: printSwiftFunction)
closureParamFunction(closure: printSwift)

closureParamFunction {
    print("프린트 종료 - 후행 클로저 사용")
}

func closureCaseFunction(a: Int, b: Int, closure: (Int) -> Void) {
    let c = a + b
    closure(c)  // 계산 결과를 클로저로 전달
}

closureCaseFunction(a: 5, b: 2) { number in
    print("계산 결과: \(number)")
}

closureCaseFunction(a: 5, b: 2) {
    print("결과 출력")
}

요약

  • 클로저는 함수처럼 동작하며 파라미터로 전달하거나 즉시 실행하는 데 사용된다
  • 콜백 함수 역할로서 자주 활용되며, 작업 완료 후의 동작을 정의하는 데 유용하다
  • 이름 없는 클로저는 코드를 간결하게 유지하는 데 효과적이다
  • 후행 클로저 문법은 클로저를 더 가독성 좋게 작성할 수 있도록 도와준다
profile
iOS 개발자 지망생

0개의 댓글