본문 바로가기

iOS/Swift

[Swift] Closure

클로저는 {} 형식의 코드블럭 이다.

 

- 전달인자로 보낼 수 있고, 변수/상수 등으로 저장하거나 전달할 수 있으며, 함수의 반환 값이 될 수도 있다.

- 참조 타입이다.

- 함수는 클로저의 한 형태로 이름이 있는 클로저이다.

  • Named Closure : 함수
    func doSomething() {
        print("Somaker")
    }​
  • Unnamed Closure : 익명 함수 -> 보통의 Closure
    let closure = { print("Somaker") }​

 

Closure의 기본 형식

{ (Parameters) -> return Type in 로직 구현 }

 

1. 클로저를 변수나 상수에 대입할 수 있다.

let closure = { () -> () in
    print("Closure")
}

let closure2 = closure

2. 함수의 파라미터 타입으로 클로저를 전달할 수 있다.

func doSomething(closure: () -> ()) {
    closure()
}
 
doSomething(closure: { () -> () in
    print("Hello!")
})

3. 함수의 반환 타입으로 클로저를 사용할 수 있다.

func doSomething() -> () -> () {
    
    return { () -> () in
        print("Hello!")
    }
}

Closure의 축약(간소화)

: Closure는 메서드에서 요구하는 형태로 전달해야 한다.

  (매개변수 타입이나 개수, 반환 타입이 같아야 전달인자로서 전달 가능) -> 이 규칙 때문에 타입 유추가 가능해진다.

 

- 타입 생략

let reversedNames = names.sorted(by: {s1, s2 in return s1 > s2})

: sorted(by:)의 경우는 이미 (String, String) -> Bool 타입의 인자가 들어와야 되는지 알고 있기 때문에 클로저에서 타입을 명시하는것을

  생략할 수 있다.

 

- 반환타입 생략

let reversedNames = names.sorted(by: {s1, s2 in s1 > s2})

: 반환 키워드를 생략할 수 있다.

 

- 인자 이름 생략

let reversedNames = names.sorted(by: { $0 > $1 }) 

: 인자 값을 축약해서 사용할 수 있다. (인자의 표기는 $0부터 순서대로)

 

- 연산자 메서드

let reversedNames = names.sorted(by: > )

: 연산자를 사용할 수 있는 타입의 경우 연산자만 남길 수 있다.

 

 

후행 클로저 

: 클로저에 여러 줄의 표현(실행코드)이 들어가게 된다면 후행 클로저를 사용하여 함수의 뒤에 표현할 수 있다. 

 

* 마지막 전달 인자로 전달되는 클로저만 해당됨.(맨 마지막 클로저만 후행 클로저 사용 가능)

let reversedNames = names.sorted() { $0 > $1 }

 

 - 함수의 마지막 인자가 클로저 이고, 후행 클로저를 사용하면 괄호"()"를 생략할 수 있다.

let reversedNames = names.sorted { $0 > $1 } 

 

 

Escaping Closure

: 클로저가 함수의 인자로 전달되지만 함수 밖에서 실행되는 것(함수가 반환된 후 실행되는 것)Escape 한다고 하며, 

 이러한 경우 매개변수 타입 앞에 @escaping이라는 키워드를 명시해야 한다. 

 함수 사이에 실행 순서를 정할 수 있다. 

 

>  자주 사용되는 경우 

   - 비동기로 실행되는 경우

   - completionHandler(완료에 따른 처리)로 사용되는 클로저의 경우

 

@escaping을 사용하는 클로저에서는 self를 명시적으로 언급해야 한다.

func test(completionHandler: @escaping () -> Void) {
	completionHandler()
}

 

 

Auto Closure

: 인자 값이 없으며, 특정 표현을 감싸서 다른 함수에 전달 인자로 사용할 수 있는 클로저를 말한다.

  자동 클로저는 클로저를 실행하기 전까지 실제 실행이 되지 않는다. 

  즉, 실제 계산이 필요할 때 호출이 되기 때문에 계산이 복잡한 연산을 하는데 유용하다.

 

var customersInLine = ["A", "B", "C", "D", "E"]
print(customersInLine.count) // 5

let customerProvider = { customersInLine.remove(at: 0) } //해당 코드가 지나도 count가 줄지 않는다.
print(customersInLine.count) // 5

// customerProvider가 실행되었을때만 동작
print(" Now serving \(customerProvider())!") // "Now serving A!"
print(customersInLine.count) // 4

 

자동 클로저를 함수의 인자값으로 넣는 예제 (매개변수 타입 앞에 @autoclosure이라는 키워드를 사용한다)

// customerInLine is ["F", "G", "H"]
func serve(customer customerProvider: @autoclosure () -> String) {
	print("Now serving \(customerProvider())!")
}

serve(customer: customerInLine.remove(at: 0) // "Now serving F!"

 

@autoclosure는 @escaping과 같이 사용할 수 있다.

 

 

 

 

출처 :  https://medium.com/@jgj455/%EC%98%A4%EB%8A%98%EC%9D%98-swift-%EC%83%81%EC%8B%9D-closure-aa401f76b7ce

 

오늘의 Swift 상식 (Closure)

클로저(Closure)란?

medium.com

https://axe-num1.tistory.com/18

 

Swift - Closure ) 클로저 문법

클로저는 세 가지 형태가 존재합니다. 이름이 있으면서 어떤 값도 획득하지 않는 전역 함수의 형태 (Global Function) 이름이 있으면서 다른 함수 내부의 값을 획득할 수 있는 중첩된 함수의 형태 (Nes

axe-num1.tistory.com

 

'iOS > Swift' 카테고리의 다른 글

UIWebView 와 WKWebView 차이  (0) 2021.12.12
[Swift] Array, Dictionary, Set, Tuple  (0) 2021.12.12
[Swift] 메모리를 참조하는 방법 (Strong, Weak, Unowned)  (1) 2020.07.30
[Swift] Type Casting  (0) 2020.07.29
[Swift] Class 와 Struct  (0) 2020.07.03