Swift
Closures
dion_K
2020. 11. 16. 20:54
728x90
안녕하세요:)
오늘은 Closure에 대해서 알아보도록 하겠습니다~
1. Closure(클로저)
- 클로저는 비교적 짧고 독립적인 코드 조각입니다.
- 클로저는 함수와 서로 호환됩니다.
- Swift에서 클로저는 이름이 없는 함수입니다.
- 클로저를 호출할 때는 Argument Label을 사용하지 않습니다.
- 글로벌 스코프에서 단독으로 사용할 수 없기 때문에 변수나 상수에 저장해야 합니다.
{ (parameters) -> ReturnType in
statements
}
{ statements } // 가장 단순한 클로저 표현식
let a = { print("Hello, blog") }
a() // Hello, blog
// 파라미터와 리턴형이 있는 클로저
let a2 = { (str: String) -> String in
return "Hello, \(str)" // str은 파라미터 이름입니다.
}
let call = a2("blog")
print(call) // Hello, blog
// 클로저를 파라미터로 전달
typealias strClosure = (String) -> (String)
func printHello(closure: strClosure) {
print(closure("iOS"))
}
printHello { (str: String) -> (String) in
return "Hi, \(str)"
} // Hi, iOS
2. Syntax Optimization(문법 최적화)
불필요한 요소를 생략하고 단순하게 작성하는 것을 문법 최적화라고 합니다.
- 파라미터 이름과 리턴형을 생략할 수 있습니다.
- 파라미터 이름을 숏 텐더 아규먼트 이름($0...)으로 대체합니다. 그리고 파라미터 이름과 in 키워드는 생략합니다.
- { } 사이에 단일 리턴 문만 남아있을 경우 리턴 키워드를 생략합니다.
- 클로저 파라미터가 마지막 파라미터라면 트렐링 클로저로 작성합니다.
- 괄호 사이에 파라미터가 없으면 괄호를 삭제합니다.
let appleProduct = ["iPhone Pro", "ipad Pro", "Air Pod Pro", "MacBook Pro", "MacBook Air", "iMac Pro",
"iMac", "iPhone", "iPod"
]
var ProModels = appleProduct.filter( { (name: String) -> Bool in
return name.contains("Pro")
})
ProModels = appleProduct.filter( {
return name.contains("Pro")
}) // 1
ProModels = appleProduct.filter( {
return $0.contains("Pro")
}) // 2
ProModels = appleProduct.filter( {
$0.contains("Pro")
}) // 3
ProModels = appleProduct.filter() { $0.contains("Pro") } // 4
ProModels = appleProduct.filter { $0.contains("Pro") } // 5
3. Capturing Value
클로저 표현식으로 작성한 클로저는 외부에 있는 값에 접근할 때 값을 캡처합니다.
- 클로저에서 값을 바꾸면 원래 값도 바뀝니다.
- 참조를 캡처합니다.
- 클로저 내부에서 외부에 있는 값에 접근하면 값에 대한 참조를 획득합니다.
- 클로저 내부에서 값을 바꾼다면 외부에 있는 원래 값도 바뀝니다.
var num = 0
print("check point #1: \(num)") // check point #1: 0
num += 1
print("check point #2: \(num)") // check point #2: 1
num = 0 // 초기화
let a1 = {
num += 1
print("check point #3: \(num)")
}
a1() // check point #3: 1
print("check point #4: \(num)") // check point #4: 1
4. Escaping Closure
- 함수의 실행 흐름과 관계없이 실행이 가능해집니다.
- 클로저를 실행할 때까지 제거되지 않습니다.
- 클로저의 실행 흐름이 함수의 실행 흐름을 벗어나더라도 메모리 에러 없이 정상적으로 실행됩니다.
func nonEscaping(closure: () -> ()) {
print("Start")
closure()
print("End")
}
nonEscaping {
print("closure")
} // Start -> closure -> End
func Escaping(closure: @escaping () -> ()) {
print("START")
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
closure()
}
print("END")
}
Escaping {
print("CLOSURE")
} // START -> END -> CLOSURE
728x90