[swift] 클로저 사용시 발생할 수 있는 메모리 누수

클로저는 Swift에서 많이 사용되는 기능 중 하나입니다. 하지만 클로저를 사용할 때 주의해야 할 것 중 하나는 메모리 누수입니다. 클로저는 strong reference로 기본적으로 캡처되기 때문에, 클로저 내부에서 self를 사용하는 경우 메모리 누수가 발생할 수 있습니다.

클로저 내부에서의 self 사용할 때 주의점

클로저 내부에서 self를 사용하는 경우, 클로저가 외부의 객체를 강한 참조로 가지게 됩니다. 이로 인해 클로저가 외부 객체를 참조하고 있을 때, 외부 객체가 해제되지 않는 상황이 발생할 수 있습니다. 이를 막기 위해서는 클로저 내부에서 self를 약한 참조로 캡처하거나 [weak self] 또는 [unowned self]를 사용해야 합니다.

Weak reference로 self 캡처하기

class MyClass {
    var closure: (() -> Void)?
    
    func setupClosure() {
        closure = { [weak self] in
            guard let self = self else { return }
            // self 사용
        }
    }
}

위의 예시에서는 [weak self]를 사용하여 self를 약한 참조로 캡처합니다. 그리고 클로저 내부에서 self의 유효성을 확인한 후 사용합니다. 만약 self가 이미 해제되었다면, 클로저 내부의 코드가 실행되지 않습니다.

Unowned reference로 self 캡처하기

class MyClass {
    var closure: (() -> Void)?
    
    func setupClosure() {
        closure = { [unowned self] in
            // self 사용
        }
    }
}

위의 예시에서는 [unowned self]를 사용하여 self를 약한 참조로 캡처합니다. 약한 참조와 달리 강한 참조이기 때문에, 클로저 내부 코드에서 self의 유효성을 확인할 필요가 없습니다. 하지만 self가 이미 해제되었다면, 런타임 에러가 발생합니다.

메모리 누수 방지를 위한 클로저 사용 팁

클로저를 사용할 때 메모리 누수를 방지하기 위해서는 다음과 같은 팁을 따를 수 있습니다.

결론

클로저는 강력한 기능이지만, 사용할 때 메모리 누수에 주의해야 합니다. 클로저 내부에서 self를 캡처할 때는 [weak self] 또는 [unowned self]를 사용하여 메모리 누수를 방지해야 합니다. 또한, 클로저를 최대한 캡처하는 객체를 최소화하고 필요한 경우 클로저를 명시적으로 해제해야 합니다.

References