Mobile/iOS

Swift. @escaping, @autoclosure

out of coding 2018. 7. 6. 13:20

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처럼 취급한다는 것입니다.

조금은 더 짧게 구현이 가능하겠죠?