적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

초보 iOS 개발자의 일상/이슈모음집

프로토콜 사용시 주의해야 할 강한 순환 참조 문제

hongssup_ 2023. 4. 18. 23:17
반응형

‘weak' must not be applied to non-class-bound 'any …Delegate'; consider adding a protocol conformance that has a class bound

이러한 에러가 떴다. 

 

클래스 인스턴스 간에 강한 순환 참조가 발생하는 경우가 있는데

흔히 Delegate 패턴을 사용할 때 이런 문제가 발생할 수 있다. 

* Retain Cycle (= Strong Reference Cycle) : 두 클래스 인스턴스가 서로 참조를 유지하면서 메모리에서 해제되지 않아 메모리 누수가 생기는 현상

그래서 UITableViewDelegate도 다음과 같이 weak var로 정의되어 있음. 

weak var delegate: UITableViewDelegate? { get set }

 

예를 들면

요런 식으로 프로토콜을 선언하고 

protocol MyDelegate {
    func myMethod()
}
//SecondViewController
var delegate: MyDelegate?
//FirstViewController
@objc private func onClickButton() {
    let vc = SecondViewController()
    vc.delegate = self
    self.present(vc, animated: true)
}

이런식으로 뷰 컨트롤러에 delegate을 선언하면 강한 순환 참조가 발생할 수 있다. 

따라서 delegate를 초기화 할 때, weak 을 사용해서 다음과 같이 선언해주어야 한다.

weak var delegate: MyDelegate?

 

그런데 여기서 weak 을 넣어주면 위에서 말한 것 처럼 다음과 같은 에러 메시지가 뜰 수 있다. 

‘weak' must not be applied to non-class-bound 'any …Delegate'; consider adding a protocol conformance that has a class bound

해당 타입이 클래스인지 아닌지 알 수 없기 때문에 발생하는 에러라고 한다. 

그럴 때는 해당 프로토콜을 선언할 때, 다음과 같이 AnyObject 로 선언해주면 된다. 

protocol MyDelegate: AnyObject { ... }

 

 

 

** 강한 순환 참조에 대해서는 다음을 참고 -> [Swift ARC] Strong Reference Cycles 강한 순환 참조

 


참고 : 

https://stackoverflow.com/questions/33471858/swift-protocol-error-weak-cannot-be-applied-to-non-class-type

 

 

728x90
반응형