• Playground File을 보고 싶으신 분은 Github
  • 파일명 : 2019-03-25-Swift-Study-Syntax.23.playground

  • Closure

  • 지금까지 공부를 해오면서 Closure에 대한 부분을 너무 그냥 저냥 넘기다보니 코딩을 하다가 클로저 문법을 만나면 굉장히 멈칫하게 되고 스스로 좌절하게 되었다 코드 자체를 읽지를 못하니 프로그램 자체를 이해하지 못하는 지경에 와서 한번 Closure 문법을 정리하면서 정복까지 해보자는 생각으로 오늘 Closure를 공부하게 되었다
  • 가장 먼저 클로저 문법을 보기 전 이해하는 단계를 거쳐야 한다
  • 클로저(Closure)를 이해하기 위해서는 꼭 알아야하는 한가지가 있는데 그것이 바로 함수형 프로그래밍에 대한 개념이다
  • 스위프트는 객체 지향 언어이자 동시에 함수형 언어이다
  • 클로저 떄문에 스위프트가 함수형 언어라고 불리우는 이유다 라고 하는 사람들도 있다
  • 그래서 클로저를 이해하기 위해서는 함수형 프로그래밍에 대한 이해가 필요한 것이다
  • 함수형 프로그래밍의 특징 첫번째 기존의 사고방식을 바꿔 대입문을 잊어야 한다
  • 위의 설명에 대한 이해를 돕기 위해 예제 코드와 함께 봐보자

  • Example

  • 첫번째 예제
func introduce() {
    print("저는 Vincent 입니다")
}

introduce() // 저는 Vincent 입니다
  • 두번쨰 예제
({ () -> Void in
    print("저는 Vincent 입니다")
})() // 저는 Vincent 입니다
  • 위의 두 예제를 보면 첫번쨰 예제는 항상 봐왔던 함수이다, 두번째 예제는 클로저 표현식으로 선언된 함수이다
  • 그러나 클로저 표현식으로 선언된 두번째 예제는 이름이 없다, 그래서 익명함수라고도 한다
  • 위의 설명에서 처음에 기존의 사고방식을 바꿔 대입문을 잊어야 한다고 했었다
  • 그 이유가 단적으로 위의 예제에서 들어난다, 바로 대입문 없이 프로그래밍을 하기 때문이다.
  • 즉, 함수형 프로그래밍을 단적으로 말하면 대입문 없이 프로그래밍하는 것이라고 말 할 수 있다.
  • 다시 한번 예제를 보면서 이해를 해보자

  • Example

  • 예제 1
let getItem = { () -> Void in
    print("득템!!")
}

getItem() // 득템!!
  • 예제 2
({ ( ) -> Void in
    print("득템!!")
})() // 득템!!
  • 예제 1은 대입을 하여 값을 출력하였지만 예제 2는 대입문 없이 예제 1과 독같은 값을 반환하도록 할 수 있다
  • 대입을 해서 어떠한 값을 할당하고 반환받고 하는 항상 늘 생각해왔던 사고방식과는 다르다

  • 함수형 프로그래밍의 두번쨰 특징 참조투명성(Referential transparency)이다
  • 참조 투명성이란 정의를 가지고 있는 문장의 어디에서나 동일한 단어라면 그 단어를 서로 맞바꾸어 놓아도 그 문장이 가지고 있는 원래 의미가 절대 변하지 않는 것을 의미한다
  • 예를 들어 설명하자면, f(x) = x + 1이라고 할 때, y = f(x) + 1이라고 하자, 그렇다면 y = x + 1 + 1은 앞의 식과 다른 식인가 라고 물었을때 아니라고 답이 나온다
  • 이 처럼 이 식이 가지고 있는 원래의 의미는 절대 변하지 않는다는 것이다
  • 메모리의 관점에서 본다면, 한번 값이 할당된 메모리 위치에는 새로운 값을 다시 할당하지 않는 다는 것이 참조 투명성의 필수 조전이다
  • 이러한 필수 조건이 만족된다면, 어떤 함수를 엄청 많이 호출(callback)을 하더라도, 항상 동일한 결과값을 얻게 되는 것이다. 프로그램이 사용하는 컴퓨터 메모리의 값이 프로그램이 실행되는 동안에는 절대 변하지 않는다
  • 대입문이 없으니까 메모리에 적재가 되는 것이 아니고 말뜻 그대로 불러오는 것(Callback하는 것)이다
  • 위에 구구절절 길게 썻으나 딱 말하자면 함수를 호출할 때 몇 천번을 호출하든지에 관계 없이 항상 동일한 결과값을 얻게 된다는 이야기이다
  • 위의 예시를 인용하여 말해보자면 f(x)라는 함수가 어디에 있든지 이 함수 호출 부분을 몇번 호출하든지 상관 없이, 이 f(x)가 쓰이는 부분은 함수의 결과값으로 대체할 수 있다는 것을 의미한다
  • 지금부터의 설명이 가장 중요하다
  • 그래서 클로저를 사용하는 이유는 멀티스레드 때문이다. iOS의 메인스레드는 UI와 관련된 일을 순차적으로 처리한다
  • 만약에 네트워크를 처리해야할 떄, 네트워크가 연결될 동안 놀고 있는 것이 아니라 다른 것들을 준비하고 있어야 한다
  • 이떄 클로저가 필요한데 네트워크를 불러오는게 끝났다면 그 시점부터 바로 다음 것을 실행 시키도록 불러온다(callback)
  • 클로저는 주로 콜백함수로서 사용하는데 1239012개의 프로세서들이 서로 먼저 이 메모리 값을 사용하려 하고, 콜백 함수가 불러질 때마다 다른 메모리에 적재된다면 엄청난 부하가 걸릴것이다
  • 메모리의 어떤 위치에 맨 처음 한번만 값을 할당하고 프로그램이 실행되는 동안 이 값을 변경하지 않는다면, 수많은 프로세서들이 서로 먼저 이 메모리 값을 사용하려고 한다 해도 신경 쓸 필요가 없다
  • 그래서 클로저를 사용하는 것이다