학습
Swift 클로저(Closure) 심화
Swift 클로저(Closure) 심화 — 중급
클로저(Closure) 심화
1. 도입 (왜 배워야 하는가)
Swift에서 클로저는 코드의 재사용성과 가독성을 높이는 중요한 도구입니다. 클로저를 이해하고 활용하지 못하면, 코드가 복잡해지고 유지보수가 어려워질 수 있습니다. 실무에서는 비동기 작업, 콜백 처리, 그리고 이벤트 핸들링 등에 클로저를 많이 사용합니다. 이를 모르면 코드가 길어지고 복잡해져 가독성이 떨어지며, 버그를 유발할 가능성이 높아집니다. 따라서 클로저를 제대로 이해하고 활용하는 것은 개발자로서 필수입니다.
2. 핵심 개념 설명
클로저는 코드의 블록을 정의하는 기능으로, 함수와 비슷하지만 이름이 없고, 세 가지 유형이 있습니다:
- 일반 클로저: 간단한 코드 블록
- 트레일링 클로저: 함수 호출 시 마지막 매개변수로 클로저를 사용할 때
- 클로저 캡처: 변수의 값을 캡처하여 사용하는 기능
비유
클로저는 마치 요리 레시피와 같습니다. 요리사가 레시피를 보고 특정 요리를 만들 때, 레시피를 잊어버리면 요리를 제대로 만들 수 없습니다. 클로저도 마찬가지로 특정 작업을 수행하기 위한 코드 블록을 정의하고 이를 호출함으로써 기능을 수행합니다.
관련 용어 정리
| 용어 | 설명 |
|---|---|
| 클로저 | 코드의 블록으로, 변수나 상수를 캡처할 수 있는 기능 |
| 트레일링 클로저 | 함수의 마지막 매개변수로 클로저를 사용할 때의 문법 |
| 캡처 | 클로저가 외부 변수에 접근해 그 값을 기억하는 것 |
3. 기본 코드 예제
다음은 클로저를 간단히 사용해 보는 예제입니다.
let greet = { (name: String) in
print("안녕하세요, \(name)님!")
}
greet("홍길동")
// 실행 결과: 안녕하세요, 홍길동님!
let greet = { (name: String) in: 클로저를 정의하고 name이라는 매개변수를 받음print("안녕하세요, \(name)님!"): 클로저에서 받은 name을 사용하여 인사말 출력greet("홍길동"): 클로저를 호출하며 "홍길동"을 인자로 전달// 실행 결과: 안녕하세요, 홍길동님!: 클로저가 실행되며 인사말이 출력됨4. 실전 활용 예제
1. 비동기 작업에서 클로저 사용
쇼핑몰에서 상품 정보를 비동기적으로 가져오는 경우가 많습니다. 클로저를 사용해 데이터를 가져온 후 UI를 업데이트하는 예시입니다.
func fetchProductData(completion: @escaping ([String]) -> Void) {
// 비동기 작업 시뮬레이션
DispatchQueue.global().async {
let products = ["상품1", "상품2", "상품3"]
// 작업 완료 후 클로저 호출
completion(products)
}
}
fetchProductData { products in
print("받은 상품 목록: \(products)")
}
// 실행 결과: 받은 상품 목록: ["상품1", "상품2", "상품3"]
2. 배열 정렬에서 클로저 사용
배열을 정렬할 때 클로저를 사용하여 정렬 기준을 정의할 수 있습니다.
let numbers = [5, 2, 8, 3, 1]
let sortedNumbers = numbers.sorted { $0 < $1 }
print(sortedNumbers)
// 실행 결과: [1, 2, 3, 5, 8]
5. 흔한 실수와 주의사항
1. 클로저 캡처
변수를 캡처하는 방식에 주의해야 합니다. 아래 예제는 잘못된 예입니다.
var count = 0
let increment = { count += 1 } // count를 캡처
increment()
print(count) // 실행 결과: 1
올바른 코드
변수를 캡처하기 위해 weak 또는 unowned를 사용해야 메모리 누수를 방지할 수 있습니다.
class Counter {
var count = 0
lazy var increment: () -> Void = { [weak self] in
self?.count += 1
}
}
let counter = Counter()
counter.increment()
print(counter.count) // 실행 결과: 1
2. 트레일링 클로저 사용
트레일링 클로저를 사용하지 않으면 코드가 불필요하게 복잡해질 수 있습니다.
func performAction(action: () -> Void) {
action()
}
performAction {
print("액션 수행")
}
// 실행 결과: 액션 수행
6. 정리
다음에 학습하면 좋은 주제: 비동기 프로그래밍 및 Swift의 Combine 프레임워크.