Swift 클로저

  1. 클로저란? 함수를 객체처럼 사용하며, 함수처럼 정의한 후에 사용 시에 부가 기능을 더 추가할 수 있도록 한 API를 의미하며 형태는 함수나 코드 블록으로 구성된다.
    1. 클로저 사용 API
      1. 클로저의 함수 타입을 결정한다.
        1. 함수 타입 : 함수 객체를 참조 변수로 사용할 때의 타입을 의미한다.
          1. 사용방법
            1. 파라미터가 없고, 반환값이 없는 함수 타입 : () -> (), () -> Void
            2. 파라미터가 있고, 반환값이 있는 함수 타입 : (Int) -> Int
      2. 클로저 표현식
        1. 별도의 함수 정의 없이 Inline 방식으로 작성한다.
          클로저 표현식
          // 방식
          { (파라미터, ...) -> Return Type in
             // 코드
          }

          // 예시
          array.sorted(by : {(a : Int, b : Int) -> Bool in
             return a < b
          })
        2. 클로저 표현식 단축
          1. 파라미터 타입 선언 생략
            array.sorted(by : {a, b -> Bool in return a < b})
          2. 1줄 return인 경우 return 생략
            array.sorted(by:{a, b -> Bool in a<b})
          3. 반환 타입 선언 생략
            array.sorted(by:{a, b in a<b})
          4. 파라미터 선언 생략
            array.sorted(by : {$0 < $1})
      3. 반환 값으로 사용한다.
        반환 값으로 사용
        // 반환 값의 함수 타입 : () -> Void
        func greeting() -> (() -> Void) {
           // 함수 타입이 () -> Void 로 함수로 구성
           func sayGoodmorning() {
               print("Good Morning Everyone")
           }
           return sayGoodmorning
        }

        // 사용하기
        let ret = greeting()
        ret() // Good Morning Everyone 출력

        // 클로저 표현식으로 작성(Inline으로 작성)
        // 코드 블록으로 구성
        func greeting() -> (() -> Void) {
           return { () -> Void in
               print("How are you")
           }
        }
      4. 파라미터로 사용한다.
        파라미터 사용하기
        // 원래 함수
        func add(_ i : Int, _ j : Int) -> Int {
           let sum = i + j
           return sum
        }
        // 함수 타입 : (Int) -> Void
        func add(_ i : Int, _ j : Int, _ handle : ((Int) -> Void)) {
           let sum = i + j
           handle(sum)
        }


        // 사용하기
        add(3, 4, {(result : Int) -> Void in
            print("3 + 4 = \(result)")
        })
      5. 프로퍼티에 사용한다.
        프로퍼티에 사용
        // 클래스 정의
        // 함수 타입 : () -> Int
        class MyClass {
           var property : (() -> Int)!
        }

        // 사용하기
        var obj = MyClass()
        obj.propery = {
           return 0
        }
      6. 클로저에서 프로퍼티 접근 : self를 사용하여 접근
        프로퍼티 접근
        // 클래스 정의
        // 함수 타입 : () -> Void
        class MyClass {
           var value = 0
         
           func showAndPrint() -> (() -> Void) {
               return {
                   print(self.value)
               }
           }
        }
      7. 클로저와 타입 알리아스
        1. 타입 알리아스는 타입에 이름을 주어 해당 타입 대신에 타입 알리아스로 정한 이름으로 대체가 가능하게 한 방법이다.
          타입 알리아스
          // 타입 알리아스 정의
          typealias Century = Int
          // 타입 알리아스 사용
          var thisEra : Century = 12 // Int 대신 사용 가능

          // 클로저에서 타입 알리아스 활용
          // 원래 함수
          func add(_ i : Int, _ j : Int) -> Int {
             let sum = i + j
             return sum
          }
          // 함수 타입 : (Int) -> Void
          func add(_ i : Int, _ j : Int, _ handle : ((Int) -> Void)) {
             let sum = i + j
             handle(sum)
          }
          // 타입 알리아스 정의
          typealias ResultHandler = (Int) -> Void
          // 함수 타입 : (Int) -> Void
          func add(_ i : Int, _ j : Int, _ handle : ResultHandler) {
             let sum = i + j
             handle(sum)
          }
          // 타입 알리아스에 정의된 이름으로 대체 가능