본문 바로가기

iOS

iOS - Closure 최적화

 

Closures최적화 


- Github에는 많은 사람들이 자신의 iOS앱 코드를 Public으로 올려놓아서 저희가 참고로 활용할 수 있는데요, 그런데 많은 코드들을 보면 아래와 같이 $0, $1, $2... 표시로 된 클로저 형태를 발견 할 수 있습니다. 저도 처음 접했을 때는 저게 클로저라는 걸 몰랐었는데요, 클로저 최적화를 적용한 코드는 많은 개발자들이 사용하기 때문에 꼭 알아두어야 한다고 생각합니다. 



예:

products.filter {

$0.contains(“Pro”)

}

그럼 클로저 최적화를 위한 5가지 규칙을 알아 봅시다.



1. 파라미터 형식과 리턴형을 생략한다. 

- 컴파일러가 자동으로 클로저의 반환타입을 정의. 컴파일러가 구문내의 반환값을 찾아 해당하는 타입으로 전환. 

- 파라미터의 타입은 컴파일러가 실제로 대입되는 값을 기반으로 추론.

예: value.sort(by: { s1, s2 in return s1 > s2 }



2. 파라미터이름을 생략하고 shorthandargument이름으로 대체한다. 

매개변수가 생략되면 매개변수명 대신 $0, $1같은 이름으로 할당된, 내부 상수를 이용할 수 있음.이 값은 입력받은 인자값의 순서대로 매칭. 

s1대신 $0, s2 대신 $1 이 사용.

바디구문만 남게 되어 in 도 필요없음. 

{ return $0 > $1 }

3. 단일 리턴문이라면 리턴 키워드를 생략한다. implicit return 

value.sort(by: { $0 > $1}

클로져가 마지막 파라미터라면 트레일링 클로저로 작성. - 함수의 마지막 인자값이 클로저일때 이를, 인자값 형식으로 작성하는대신 함수의 뒤에 꼬리처럼 붙일 수 있는 문법.- 이때 argument label을 생략한다.

value.sort() { $0 > $1 } 





4. 괄호사이에 파라미터가 더이상 없다면 괄호를 생략한다. 

value.sort{$0 > $1}

 

클로저 문법 최적화

스위프트는 단순한 문법을 선호함.

컴파일러가 추론가능한 것은 생략하는 것을 지향. 

위에 5가지 규칙 중 특히 헷갈릴 수 있는 Shorthand Argument 와 Trailing Closure에 대해서 알아봅시다.



Shorthand argument - 스위프트 클로저는 Shorthand argument name이라는 것을 지원하는데, $0, $1, $2 ... 형식으로 표시하고, 넘어오는 인자의 순서에 맞게 매칭된다.

즉, $0, $1, $2는 클로저로 넘어오는 첫번째, 두번째, 세번째 인자를 의미한다. 

다시말해, 클로저를 만들때 파라미터 부분을 생략하고 그냥 본문에서 $0, $1로 인자값을 받아 사용하는 것이 가능하다.

클로저 앞쪽에 오는 인자 부분이 없으니 뒤에 오던 in 마저 생략 할 수 있다 (in의 목적은 클로저 바디가 시작 되는 것을 표시하는 것인데, 선언부가 없으니 바디를 구분할 이유가 없어졌기 때문임)



Tailing Closure

스위프트에는 Tailing Closure라는 것이 형식이 있는데, 이 방법은 함수의 마지막 인자로 클로저를 넘길때 사용한다 (특히, 클로저가 길 때).

func doSomething(name: String, callback: (s: String) -> Void) {

    callback(s: name)

}

먼저 doSomething(name: callback:)함수가 있다고 가정하자. 

첫번째 파라미터는 문자열이고, 두번째는 (s: String) -> Void 타입의 클로저다 (Void는 리턴값이 없음을 의미함).

함수가 하는 일은 두번째 인자로 받은 클로저를 호출하는 것이며, 이때 인자값으로 name을 넘겨준다 (잘 볼 것)

앞의 코드는 함수 선언 부분이었으니, 이제 함수를 호출해 보자.

doSomething(name: "Tolik", callback: {

    (s) -> Void in

    print("Hello " + s)

})

이 코드는 앞에서 배운 일반적인 방법으로 클로저를 호출 하는 것이다. 

물론 출력은 "Hello Tolik" 이 된다.

이제 Tailing Closure로 호출해 보자

doSomething(name: "Tolik") {

    (s) -> Void in

    print("Hello " + s)

   }

보통 함수를 호출 할 때는 doSomething(...)이런식으로 괄호로 끝나야 하는데, 여기서는 그렇지 않다. 

뒤에 { } 블록이 붙어 마치 함수를 선언하는 것 처럼 생겼다.

doSomething(name: callback:) 를 Tailing Closure 방식으로 호출 한 것이다. 

Tailing Closure 방식 호출은 마지막 인자를 () 안에 넣지 않고 밖으로 뺀다. 이때 마지막 인자의 이름(callback:)은 쓰지 않는다.

클로저 표현식은 주로 함수의 인자값으로 주는 경우가 많다(inline closure)

클로저를 함수의 인자값으로 주는 경우가 매우 많다. 

트레일링 클로저는 함수의 마지막 인자값이 클로저일때 , 인자값 형식으로 전달하는 대신 함수의 뒤에 꼬리처럼 붙일 수 있는 문법을 의미함. 주의할 점은 이 때 인자 레이블은 생략된다. 주의: 함수의 마지막 인자값에만 적용.

 

 

'iOS' 카테고리의 다른 글

Source Control with Xcode  (0) 2020.07.09
iOS - Defer문  (0) 2020.05.07
iOS - JSON Parsing  (0) 2020.04.27
iOS - ARC, Weak, Unowned  (0) 2020.04.11
iOS - Cocoa Pods  (0) 2020.04.09