안녕하세요. 클로저를 공부하게 되면서 클로저의 Escaping과 Capture List에 대한 내용을 정리해보려고 합니다.
[클로저의 Escaping]
클로저의 escaping 이란 어떤 함수에서 인자 값으로 클로저를 전달을 받을 때 이 클로저가 함수가 종료된 후에도 클로저를 호출할 수 있는 경우에 escaping이라고 합니다.
func downloadImage(imageURL: URL, completionHandler: @escaping (UIImage?) -> Void) {
let task = URLSession.shared.dataTask(with: imageURL) { data, response, error in
if let data = data, let image = UIImage(data: data) {
completionHandler(image)
}
}
task.resume()
}
위는 이미지를 다운로드하는 downloagImage(imageURL: completionHandler:) 함수를 예를 들어보았습니다. 함수 내부에서는 URLSession 객체에 있는 dataTask 메서드를 이용하여 비동기 실행을 하고 있습니다. 이때 completionHandler가 호출이 되고 있는데, downloadImage 함수가 끝나도 completionHandler는 살아있어야 비동기 처리 후 호출이 가능합니다. 그래서 @escaping 키워드를 붙여서 탈출 클로저를 만들어야 합니다.
[클로저의 Capture List]
클로저의 캡처 리스트는 캡처된 외부 변수나 상수를 대괄호’[]’로 이용하여 목록을 나열한 리스트입니다. 이것은 클로저가 어떤 변수를 캡처하고 어떤 방식으로 사용하는지를 명시적으로 나열하는 역할을 합니다.
값 타입의 경우와 참조 타입의 경우에 대해서 예시를 들어보겠습니다.
값 타입인 구조체를 예를 들어보겠습니다.
struct Person {
var name: String
}
var person: Person = Person(name: "James")
print("1. name = \(person.name)")
let closure: () -> Void = { [person] in
print("2. name = \(person.name)")
}
person.name = "Mike"
print("3. name = \(person.name)")
closure()
// 1. name = James
// 3. name = Mike
// 2. name = James
이 예시에서, 캡처 리스트를 사용하여`person`이라는 외부 변수를 클로저 내부로 캡처했습니다. 이 클로저는 외부 `person`의 값을 복사하여 저장하므로, 외부에서 `person`의 값이 변경되어도 클로저 내부에 영향을 주지 않습니다.
이것은 값 타입의 변수가 캡처 리스트를 통해 캡처될 때 발생하는 동작입니다. 캡처 리스트는 클로저와 외부 변수 간의 독립성을 유지하는 데 도움을 줍니다.
이번에는 참조 타입인 클래스를 예를 들어보겠습니다.
class Person {
var name: String
init(name: String) {
self.name = name
}
}
var person: Person = Person(name: "James")
print("1. name = \(person.name)")
let closure: () -> Void = { [person] in
print("2. name = \(person.name)")
}
person.name = "Mike"
print("3. name = \(person.name)")
closure()
// 1. name = James
// 3. name = Mike
// 2. name = Mike
이 예시에서, 캡처 리스트를 사용하여 `person`이라는 외부 변수를 클로저 내부로 캡처했습니다. 이 클로저는 외부 `person`을 참조하고 있으며 외부에서 `person`의 값이 변경될 때 클로저 내부에서도 변경된 값을 사용합니다.
이것은 참조 타입 변수가 캡처 리스트를 통해 참조되어 외부 및 클로저 간에 동일한 인스턴스를 참조한다는 것을 보여줍니다.
지금까지 Swift의 클로저에서 escaping과 capture list에 대해서 살펴보았습니다.
'Swift' 카테고리의 다른 글
[Swift] 스위프트 메모리 관리 (2) | 2023.10.26 |
---|---|
[Swift] deinitializer 활용 (1) | 2023.10.26 |
[Swift] 상수와 변수 (0) | 2023.10.23 |