[iOS]_DelegatePattern

윤여송·2023년 11월 15일
0

iOS

목록 보기
10/11
post-thumbnail

DelegatePattern

📚Swift의 Delegate Pattern이란?

Swift에서 Delegate Pattern은 객체 간 상호 작용을 처리하는 방법 중 하나입니다.
이 패턴은 객체 간 결합도를 낮추고 유지 보수성을 높이기 위해 사용됩니다.

Delegate는 프로토콜로 정의됩니다. 이 프로토콜은 다른 객체에게 자신의 메서드를 구현하도록 요구합니다. 이렇게 구현된 메서드는 델리게이트 객체에게 호출되며 이를 통해 해당 객체는 델리게이트 객체와 상호작용할 수 있게 됩니다.

💡예제

1.프로토콜 정의하기

먼저, 프로토콜을 정의합니다.
아래 코드에서는 MyViewDelegate라는 프로토콜을 정의합니다.
이 프로토콜은 didTapButton()이라는 메서드를 정의하고 있습니다.

protocol MyViewDelegate: AnyObject {
func didTapButton()
}

2.Delegate 객체 생성하기

다음으로, 델리게이트 객체를 생성합니다. 여기서 델리게이트 객체는 프로토콜을 채택하고 있는 객체를 말합니다.

아래 코드에서는 MyViewController 클래스를 정의하고, 이 클래스는 MyViewDelegate 프로토콜을 채택하고 있습니다. didTapButton() 메서드를 구현하여 해당 메서드가 호출될 때 로그를 출력하도록 해봅시다.

class MyViewController: UIViewController, MyViewDelegate {
	override func viewDidLoad() {
    	super.viewDidLoad()
        
        let myView = MyView()
        myView.delegate = self
        
        view.addSubview(myView)
        myView.snp.makeConstraints { make in
        	make.edges.equalToSuperview()
        }
    }
    
    func didTapButton() {
    	print("Button Tapped!")
    }
}

myView.delegate = self 가 의미하는 바를 알게 되면 이해하기 쉽습니다. 여기서 selfMyViewController 객체를 가리킵니다. 즉, MyViewController 객체가 MyView 객체의 델리게이트(대리자) 로 동작하도록 설정하는 것입니다. 앞서 설명했던 것처럼 델리게이트 패턴에서, 델리게이트 객체는 프로토콜을 채택한 객체입니다. MyViewDelegate 프로토콜을 채택한 객체는 MyView 객체의 델리게이트가 될 수 있게 되는 것이죠. 따라서, MyViewController 객체가 MyViewDelegate 프로토콜을 채택하고 있으므로, MyViewController 객체가 MyView 객체의 델리게이트로 동작할 수 있는 것입니다.

정리하면 myView.delegate = self 코드는 MyView 객체의 delegate 프로퍼티에 MyViewController 객체(self)를 할당하는 역할을 합니다. 이렇게 함ㅅ으로써, MyView 객체에서 버튼을 탭할 때마다, MyViewController 객체의 didTapButton() 메서드가 호출되어, MyViewController 객체에서 추가적인 작업을 수행할 수 있도록 합니다.

3.뷰 객체 생성하기

마지막으로, MyView 클래스를 정의합니다.
이 클래스는 UIButton을 포함하고 있으며, 버튼이 탭되면 didTapButton() 메서드를 호출합니다.

class MyView: UIView {
	private let button = UIButton()
    weak var delegate: MyViewDelegate?
    
    override init(frame: CGRect) {
    	super.init(frame: frame)
        
        button.setTitle("버튼", for: .normal)
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        
        addSUbview(button)
        
        button.snp.makeConstraints { make in
        	make.width.equalTo(44)
            make.height.equalTo(44)
            make.center.equalToSuperView()
        }
    }
    required init?(coder: NSCoder) {
    	fatalError("init(coder:) has not been implemented")
    }
    
    @objc func buttonTapped() {
    	delegate?.didTapButton()
    }
}

여기서 delegate객체를 weak로 선언하는 이유에 대해서 알아둘 필요가 있습니다. 결론부터 말하자면 delegate 객체가 소멸될 때 메모리 누수를 방지하기 위함입니다. 델리게이트 패턴에서 객체 A가 객체 B를 델리게이트로 설정하면 객체 B는 객체 A의 델리게이트 객체가 됩니다. 이때, 델리게이트 객체가 객체 A보다 더 오래 남아있을 수 있습니다. 이런 경우, 객체 A가 델리게이트 객체에 대한 강한 참조를 가지고 있으면, 델리게이트 객체가 소멸되지 않고 계속 살아남게 됩니다. 즉, 메모리 누수가 발생하게 되는 것입니다. 정리하면 weak로 선언하여 강한 참조를 가지지 않도록 함으로써 메모리 누수를 방지할 수 있게 되는 것입니다.

profile
y_some__velog

0개의 댓글