[swift] 클로저 사용시 주의사항

클로저란?

클로저는 스위프트에서 일급 객체로 취급되는 함수입니다. 함수로서의 역할을 하며, 다른 함수의 인자로 전달되거나 함수의 반환 값으로 사용될 수 있습니다.

주의사항

1. 클로저 캡처 명확히하기

클로저 안에서 외부 변수를 참조할 때, 변수를 캡처하게 됩니다. 이 때, 클로저가 해당 변수를 강한참조하게 되면 메모리 누수가 발생할 수 있습니다. 이러한 경우에는 capture list를 이용하여 캡처 방식을 명확히 해야 합니다. 예를 들어, [weak self] 와 같이 클로저와 생명주기를 공유하도록 해야합니다.

someFunction {
    [weak self] in
    // 클로저 내에서 self 사용
}

2. 순환 참조 문제

클로저를 사용할 때, 순환참조의 가능성을 염두에 두어야 합니다. 즉, 클로저가 인자로 전달되는데 클로저 내부에서 인자로 전달된 객체를 강한참조하는 경우 상호참조가 발생하여 메모리 누수가 발생할 수 있습니다. 이를 해결하기 위해서는 [weak self] 와 같이 약한 참조를 사용하거나, [unowned self] 와 같이 클로저의 생명주기와 객체의 생명주기가 항상 동일한 경우에만 사용합니다.

someFunction {
    [weak self] in
    guard let strongSelf = self else { return }
    // strongSelf 는 강한참조하므로 옵셔널 체이닝이 필요합니다.
}
someFunction {
    [unowned self] in
    // self 가 항상 존재하는 경우에만 사용해야합니다.
}

3. 클로저의 실행 유형 구분

클로저는 실행의 시점에 따라 크게 두 가지로 나눌 수 있습니다. 하나는 변수에 할당하여 나중에 실행되는 경우이고, 다른 하나는 즉시 실행되는 경우입니다. 즉시 실행되는 클로저는 함수와 마찬가지로 {} 로 묶여 있으며, 변수에 할당되는 클로저는 () 를 통해 실행됩니다.

// 즉시 실행되는 클로저
{ () -> Void in
    // 실행 내용
}()

// 변수에 할당되어 나중에 실행되는 클로저
let myClosure: () -> Void = {
    // 실행 내용
}

myClosure() // 클로저 실행

결론

클로저를 사용할 때에는 캡처, 순환 참조, 실행 유형 등 몇 가지 주의사항을 염두에 두어야 합니다. 클로저를 올바르게 사용하면 스위프트에서 강력한 기능을 활용할 수 있습니다.

참고문서: