Closures are self-contained blocks of functionality that can be passed around and used in your code.
Swift 1.x와 2.x 버전에서는, closure 파라미터는 @escaping
이 default이었다고 하며, Closure는 function의 body execution이 진행될 때, 탈출할 수 있다는 의미이다. 만약, Closure의 탈출 기능을 포함하지 않으려고 한다면, @nonescaping
을 명시해야 했따.
Swift 3.x으로 넘어오면서, Apple은 해당 Closure에 변화를 주었다. @nonescaping
이 default로 변화되었으며, closure는 function의 body excution과 동시에 실행되며, clousre를 탈출시키기 위해서는 @escaping
을 명시해야 한다. 왜 Apple은 해당 변화를 주었을까? 이것에 대해 마지막에 토론하고자 한다. 😀
Function argument로 closure를 넘긴다고 할 때, closure는 function body와 동시에 실행되며, Compiler를 반환한다. Exction 말미에는, scope 범위에서 벗어나며, 더이상 메모리에 상주하지 않는다.
1. Pass the closure as function argument, during the function call.
2. Do some additional work with function.
3. Function runs the closure.
4. Function returns the compiler back.
func getSumOf(array:[Int], handler: ((Int)->Void)) {
//step 2
var sum: Int = 0
for value in array {
sum += value
}
//step 3
handler(sum)
}
func doSomething() {
//setp 1
self.getSumOf(array: [16,756,442,6,23]) { [weak self](sum) in
print(sum)
//step 4, finishing the execution
}
}
//It will print the sumof all the given numbers.
Closure를 Function Argument로 전달하면 Closure는 나중에 실행될 수 있도록 보존되고, Function Body가 실행되면 컴파일러가 다시 반환된다. 실행이 종료되면 전달된 Closure의 범위는 클로저가 실행될 때까지 메모리에 존재한다. Clousre를 Escaping하는 방법은 아래와 같다.
var complitionHandler: ((Int)->Void)?
func getSumOf(array:[Int], handler: @escaping ((Int)->Void)) {
//step 2
//here I'm taking for loop just for example, in real case it'll be something else like API call
var sum: Int = 0
for value in array {
sum += value
}
//step 3
self.complitionHandler = handler
}
func doSomething() {
//setp 1
self.getSumOf(array: [16,756,442,6,23]) { [weak self](sum) in
print(sum)
//step 4, finishing the execution
}
}
//Here we are storing the closure for future use.
//It will print the sumof all the passed numbers.
func getSumOf(array:[Int], handler: @escaping ((Int)->Void)) {
//step 2
var sum: Int = 0
for value in array {
sum += value
}
//step 3
Globals.delay(0.3, closure: {
handler(sum)
})
}
func doSomething() {
//setp 1
self.getSumOf(array: [16,756,442,6,23]) { [weak self](sum) in
print(sum)
//step 4, finishing the execution
}
}
//Here we are calling the closure with the delay of 0.3 seconds
//It will print the sumof all the passed numbers.