Swift. @escaping, @autoclosure
swift의 @escaping 에 대해서 적어볼까 합니다.
개념만 알면 아주 쉬운 개념입니다.
저는 swift4를 사용합니다.
다음과 같이 우리는 function에 closure를 넘겨주어서 사용이 가능합니다.
1 2 3 | func test(block: () -> ()) { block() } | cs |
그렇다면 다음과 같으면 어떨까요?
1 2 3 4 5 | func test(block: () -> ()) { DispatchQueue.main.async { block() } } | cs |
무언가 오류가 납니다.
noescape closure가 탈출하려고 하였다고 합니다.
일반적으로 그냥 선언을 하여 주지 않는다면 @noescape가 적용되는 겁니다.
그래서 적용을 하지 않았다고 나오는거죠.
1 2 3 4 5 | func test(block: @noescape () -> ()) { DispatchQueue.main.async { block() } } | cs |
이렇게 하면 위아래로 에러가 발생합니다. 아래의 아래는 block에 대한 에러고 위는 @noescape의 에러입니다.
기본으로 @noescape가 들어가 있고, 삭제 되었으니 그냥 넣지 말라는 뜻입니다.
그럼 최종적으로는 이렇게 하면 됩니다.
1 2 3 4 5 | func test(block: @escaping () -> ()) { DispatchQueue.main.async { block() } } | cs |
closure 자체가 escaping 될수 있다는것을 선언하여 줍니다.
이유를 따지자면 function에서 다른 function을 호출하였는데, 자신의 function안에서 살아 있다가 없어져 버리기 때문입니다.
좀 어렵게 적은거 같지만 세번정도 보시면 말이 이해가 되실겁니다. ㅠ 더 쉽게 적을수 있으면 적어볼게요.
* noescape -> noescape 가능. noescape -> escaping 불가. escaping -> escaping, noescaping 모두 가능
@autoclosure
1 2 3 4 5 6 7 8 9 10 11 12 13 | func test(block: () -> ()) { block() } test { print("AAA") } func test2(block: @autoclosure () -> ()) { block() } test2(block: print("BBB")) | cs |
위의 function과 아래의 function의 차이를 느끼실수 있을까요?
1 | test { print("AAA") } | cs |
test를 이렇게 호출해도 되겠지만 뭔가 좀 어색하긴 하네요.
차이는 블럭에 들어가는 일반적인 함수 호출등을 그냥 closure처럼 취급한다는 것입니다.
조금은 더 짧게 구현이 가능하겠죠?