클로저(Closure)는 Swift에서 코드 블록을 정의하고, 다른 함수나 변수에 전달할 수 있는 일종의 익명 함수입니다. 클로저는 전달되는 곳에서 코드 블록을 나중에 실행하도록 할 수 있습니다.
1. 클로저의 기본 작동 방식
클로저는 코드 블록을 변수처럼 저장하거나 함수의 인자로 전달할 수 있습니다. 전달된 클로저는 해당 함수나 블록 내에서 호출되어 특정 작업을 실행합니다. Swift에서는 클로저가 특히 비동기 작업이나 콜백 처리에 자주 사용됩니다.
기본 클로저 정의 및 호출 예시
let simpleClosure = { (name: String) -> String in
return "Hello, \(name)!"
}
print(simpleClosure("Swift")) // 출력: "Hello, Swift!"
- simpleClosure는 문자열을 매개변수로 받아 문자열을 반환하는 클로저입니다.
- 이 클로저는 호출 시 name 인자를 받아 "Hello, Swift!"라는 결과를 출력합니다.
2. 클로저의 실행 흐름
클로저는 기본적으로 캡처 리스트를 통해 외부에서 참조하고 있는 변수나 상수의 값을 클로저 내부로 가져옵니다. 클로저가 참조한 변수들은 캡처되며, 클로저가 실행될 때 해당 값들을 사용할 수 있습니다.
예시: 변수 캡처
func makeIncrementer() -> () -> Int {
var total = 0
let incrementer: () -> Int = {
total += 1
return total
}
return incrementer
}
let increment = makeIncrementer()
print(increment()) // 출력: 1
print(increment()) // 출력: 2
- makeIncrementer 함수는 total 변수를 캡처한 클로저를 반환합니다.
- 반환된 클로저는 매번 호출될 때마다 total 값을 1씩 증가시키며, 클로저 내부에서 해당 변수의 값을 유지하고 수정합니다.
3. 클로저의 실행 시점
클로저는 전달된 후 특정 시점에서 실행됩니다. 이때 클로저는 자신이 참조하는 모든 변수 및 상태를 함께 캡처하여 작업을 수행합니다.
예시: 클로저를 함수의 인자로 사용
func performOperation(operation: () -> Void) {
print("Operation 시작")
operation() // 전달된 클로저를 실행
print("Operation 종료")
}
performOperation {
print("클로저 내부 작업 수행")
}
- performOperation 함수는 인자로 전달된 클로저를 호출하여 클로저 내부 작업을 수행합니다.
- 클로저는 전달된 후 함수 내부에서 필요한 시점에 호출됩니다.
4. 클로저의 실행 방식: 클로저는 참조를 통해 전달
클로저는 참조 타입이므로, 클로저가 전달되는 곳에서 참조에 의해 전달되고, 참조가 종료되지 않는 한 클로저는 메모리에 남아 있습니다. 이 특성은 클로저가 외부 변수의 상태를 유지하거나 값을 변경하는 비동기 작업에서 매우 유용합니다.
5. 클로저의 활용: 비동기 작업
클로저는 특히 비동기 작업에서 많이 사용됩니다. 예를 들어, 네트워크 요청을 수행한 후 데이터를 처리하거나 UI 업데이트와 같은 작업을 클로저로 전달할 수 있습니다. 비동기 작업에서는 작업이 완료된 후에 클로저가 실행되어, 그 결과를 처리합니다.
예시: 네트워크 요청 시 클로저 사용
func fetchData(completion: @escaping (String) -> Void) {
DispatchQueue.global().async {
let data = "Fetched Data"
completion(data) // 비동기 작업이 완료된 후 클로저 호출
}
}
fetchData { result in
print("받은 데이터: \(result)")
}
- fetchData 함수는 데이터를 비동기로 가져온 후, completion 클로저를 호출하여 작업이 완료되었음을 알립니다.
- 클로저는 비동기 작업 후 실행되며, 결과를 처리합니다.
6. @escaping 클로저
Swift에서 클로저는 기본적으로 비동기 작업이나 함수 실행 후에도 유지되어야 하는 경우, @escaping 키워드를 사용합니다. 즉, 함수의 실행이 끝난 후에도 나중에 호출될 수 있는 클로저를 탈출 클로저(escaping closure)라고 합니다.
예시: @escaping 클로저
func performAsyncTask(completion: @escaping () -> Void) {
DispatchQueue.global().async {
print("비동기 작업 수행 중")
completion() // 나중에 클로저가 실행됨
}
}
performAsyncTask {
print("작업 완료!")
}
- @escaping 키워드를 사용하면 클로저는 비동기 작업이 끝난 후 호출될 수 있으며, 함수의 실행이 종료된 후에도 클로저가 탈출하여 나중에 실행될 수 있습니다.
7. 클로저의 사용 사례
- 비동기 작업 (네트워크, 파일 처리):
- 클로저는 네트워크 작업이나 파일 읽기 등의 비동기 처리에 자주 사용됩니다. 작업이 완료된 후 클로저를 호출해 결과를 처리합니다.
- UI 업데이트 (SwiftUI):
- SwiftUI에서는 버튼 클릭과 같은 이벤트 처리를 클로저를 통해 수행합니다.
- 데이터 전달:
- 클로저는 하나의 뷰에서 다른 뷰로 데이터를 전달하거나 이벤트를 처리하는 데 사용할 수 있습니다. 예를 들어, 사용자가 데이터를 입력하고 저장하면 클로저를 통해 해당 데이터를 전달할 수 있습니다.
8. 클로저의 장점
- 코드 블록의 유연한 전달: 클로저는 함수나 메서드로 코드를 전달하지 않고, 바로 코드 블록을 전달할 수 있어 코드를 간결하게 작성할 수 있습니다.
- 상태 유지: 클로저는 자신이 선언된 외부 변수의 상태를 캡처하여 클로저 내부에서 사용할 수 있으므로, 비동기 작업에서 변수의 상태를 유지하면서 작업을 수행할 수 있습니다.
- 비동기 처리: 비동기 작업이 완료된 후 실행할 작업을 쉽게 정의할 수 있어, 콜백 함수로 자주 사용됩니다.
결론
- 클로저는 코드 블록을 저장하여 필요한 시점에 호출할 수 있는 매우 유용한 기능입니다.
- 클로저는 함수의 인자로 전달되어 다른 함수 내에서 실행될 수 있으며, 외부 변수를 캡처하여 그 값을 유지하거나 수정할 수 있습니다.
- 비동기 작업, 콜백 처리, 데이터 전달 등 다양한 상황에서 유용하게 사용되며, Swift의 중요한 기능 중 하나입니다.
'Category > iOS' 카테고리의 다른 글
| Podfile이란? (1) | 2024.09.29 |
|---|---|
| CocoaPods란? (0) | 2024.09.29 |
| SwiftUI - 현재 화면 닫기 @Environment(\.dismiss) (0) | 2024.09.23 |
| Spacer()란? (0) | 2024.09.23 |
| @FocusState란? (0) | 2024.09.23 |