Swift. Delegate를 간단하게 알아보자

Delegate

Posted by MinJun on Wednesday, February 14, 2018 Tags: Swift   3 minute read

- 델리게이트란?

갑자기 델리게이트란 뭘까? 생각해보니까 뭐라고 대리자.. 객체가 하는일을 대신해주는.. 이라고 밖에 생각이 들지 않아서 한번 정리 하려고 글을 작성합니다.

델리게이트 객체란 다른 객체의 변화에 대응하거나, 다른 객체의 행동에 변화를 줄 수 있는 개체를 일컫는다. 델리게이트 패턴의 기본적인 원칙은, 두 객체가 힘을 합쳐서 문제를 해결한다는 것입니다. 첫번째 객체는 매우 범용적으로 여러 가지 상황에 재사용할 수 있는 성격을 지니며, 두 번째 객체에 대한 레퍼런스를 저장해 놓고 중요할 때마다 메시지를 전송하는 역할을 합니다.

델리게이트의 장점은 객체의 행동을 단순화하면서 객체 간의 결합성을 최소화시키는데 있습니다.


예제 코드

class MJViwe: UIView {
    var delegate: MJViewDelegate? {
        willSet{
            DispatchQueue.main.async {
                self.changeBackGroundColor()
            }
        }
    }
    
    // View의 배경색을 바꾸어 주는 함수
    func changeBackGroundColor() {
        self.backgroundColor = delegate?.changeBackGroundColor()
    }
}

protocol MJViewDelegate {
    func changeBackGroundColor() -> UIColor
}

MJViewDelegate라는 프로토콜을 체택해서, 해당 객체가 해야하는일을 MJviewDelegate 프로토콜에 정의한 함수를 호출해서 대신 일을 시켜줍니다.(?) 그리고 상황에 따라서 다르겠지만, 델리게이트 패턴에서 delegate라는 프로퍼티가 weak가 되어야 할 때도 있습니다. 잘못하면 Retain Cycles가 발생 할 수도 있기 때문입니다. 상황에 따라서 이지, 필수는 아닙니다.

// Delegate 프로토콜을 채택합니다.
class ViewController: UIViewController, MJViewDelegate {

	// 해당 함수를 실행해서, View의 배경색을 변경 시켜줍니다.
    func changeBackGroundColor() -> UIColor {
        let color: UIColor = UIColor.red
        return color
    }
    
    var someView: MJViwe = MJViwe(frame: CGRect(x: 50,
                                                y: 50,
                                                width: 200,
                                                height: 200))
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(someView)
        someView.delegate = self
    }
}

someView의 배경색을 변경하는 코드를 someView자체가 실행하지 않고, Protocol을 통해서 변경 해주었습니다. someView.delegate = self에 왜 self 넣고 실행하는지 궁금 하다면 http://seorenn.blogspot.kr/2014/06/swift-protocols.html를 참조하면 좋을것 같습니다.


왜 사용하는지?

Delegate 패턴과 비슷하게 사용될 수 있는 Notification, Closure가 있지만 Delegate를 사용하는 이유는 목적이 다릅니다. 그럼 언제 Notification을 사용하고 언제 Delegate를 사용하냐? 라고 한다면, 메세지를 수신받는 객체가 많을때는 Notificaiton, 하나의 객체가 여러가지 요구를 받는다면 Delegate를 사용합니다. Closure와 Delegate는 유사하게 사용되지만, Delegate를 Closure로 구현하면 불편하고 고민 거리가 많이 생기게 됩니다.


Reference

Seorenn님 Blog
코코아 디자인 패턴