[swift] 참조 순환 예방을 위한 디자인 패턴

iOS 앱을 개발하다 보면 참조 순환(reference cycles) 문제가 발생할 수 있습니다. 객체가 서로를 강한 참조하는 경우 메모리 누수가 발생할 수 있으며, 이를 해결하기 위해 디자인 패턴을 사용할 수 있습니다.

디자인 패턴: 약한 참조(Weak Reference) 및 비소유 참조(Unowned Reference)

약한 참조는 객체를 가리키지만 관리되는 참조가 아니기 때문에 객체가 메모리에서 해제될 수 있습니다. 비소유 참조는 객체를 가리키지만 참조 횟수를 증가시키지 않기 때문에 객체가 메모리에서 해제될 때 자동으로 nil이 할당됩니다.

class Person {
    var card: CreditCard?
}

class CreditCard {
    weak var owner: Person?
}

var john: Person?
var visa: CreditCard?

john = Person()
visa = CreditCard()

john!.card = visa
visa!.owner = john

이 예제에서 johnvisa가 서로를 강한 참조하고 있기 때문에 참조 순환 문제가 발생하게 됩니다.

weak var owner: Person?

이를 해결하기 위해 owner 속성을 약한 참조로 변경하여 참조 순환을 방지할 수 있습니다.

디자인 패턴: 클로저(Closure)에서의 참조 순환 방지

클로저 내부에서 self 참조를 피하기 위해 약한 참조를 사용할 수 있습니다. 클로저에서 self를 캡쳐할 때 [weak self] 또는 [unowned self]를 사용하여 참조 순환 문제를 해결할 수 있습니다.

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = { [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name)/>"
        }
    }
}

결론

참조 순환은 메모리 누수를 초래할 수 있는 심각한 문제입니다. 약한 참조와 비소유 참조를 활용하여 객체 간의 참조 순환을 효과적으로 방지할 수 있습니다. 클로저에서의 참조 순환 문제를 해결하기 위해서는 클로저 내부에서의 self 참조를 적절히 해제해주는 것이 중요합니다.

참조 순환 문제를 해결하여 안정적이고 효율적인 앱을 개발할 수 있도록 주의 깊게 관리해야 합니다.

참조


본 문서는 iOS 앱 개발에서 발생하는 참조 순환 문제를 해결하기 위한 디자인 패턴에 대해 설명합니다. 참조 순환 문제를 예방하고 클린한 코드를 유지하기 위해서는 디자인 패턴을 적절히 활용하는 것이 중요합니다.