본문 바로가기
iOS - 실무관련/iOS

Delegate 패턴

by print_soo 2022. 6. 12.
아래의 글은 해당 블로그를 참고하여 작성하였습니다. (+ 다른 블로그)

 

1. Delegate는 무엇인가?

Delegate란 어떤 객체가 해야 할 일을 부분적으로 확장해서 대신 처리한다. 

 

 

 

2. Delegate는 어디에 사용되는가?

Delegate는 두 가지만 기억하면 된다. 

1. 처리하라고 시키는 객체
2. 대신 처리해줄 객체

 

0. 상황

 

상황: 여러곳에서 사용할 수 있는 메시지 창을 만들려고한다. 메시창에는 버튼이 있고 해당 버튼을 누르면 ViewController는 무슨 버튼을 눌렀는지 확인해서 그 버튼이 이벤트가 발생하면 해야하는 일들을 처리해야 한다고 한다. 

 

 

1. 처리하라고 객체 

 

우선 대신 처리하라고 시키는 객체를 만들기 전에 우리는 객체의 프로토콜을 선언해주는 작업이 필요하다. (이후 대신 처리해줄 객체에서 채택작업을 할 예정)

 

그후 해당 일을 처리하라고 시키는 객체인 메시지창을 만들어준다.

 

import UIKit

protocol MessageBoxDelegate: class { //프로토콜 선언
  func touchButton()
}

class MessageBox: UIView {

  weak var delegate: MessageBoxDelegate?
  var button: UIButton?

  public override init(frame: CGRect) {
    super.init(frame: frame)

    configure()
  }

  public required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    configure()
  }

  func configure() {
    button = UIButton(type: .system)
    if let btn = button {
      btn.setTitle("SEND", for: .normal)
      btn.sizeToFit()
      btn.frame.origin = CGPoint(x: (self.bounds.width - btn.bounds.width) * 0.5,
                                 y: (self.bounds.height - btn.bounds.height) * 0.5)
      btn.addTarget(self, action: #selector(tapButton), for: .touchUpInside)
      self.addSubview(btn)
    }
  }

  func tapButton() {
    delegate?.touchButton()
  }
}

 

 

 

2. 이제 프로토콜을 채택하고 대신 처리해줄 객체를 만든다. 

 

import UIKit


class ViewController: UIViewController {

  var messageBox: MessageBox?

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    messageBox = MessageBox(frame: CGRect(origin: .zero, size: CGSize(width: 300, height: 200)))
    if let msg = messageBox {
      msg.frame.origin = CGPoint(x: (UIScreen.main.bounds.width - msg.bounds.width) * 0.5,
                                 y: (UIScreen.main.bounds.height - msg.bounds.height) * 0.5)

      msg.backgroundColor = .lightGray
      msg.delegate = self
      self.view.addSubview(msg)
    }
  }
}

extension ViewController: MessageBoxDelegate { //ViewController에 프로토콜 채택작업
    func touchButton() {
    print("touchButton")
  }
}

 

 

여기서 의문점이 생기는 아래의 코드가 있다. 

msg.delegate = self

이 코드는 Delegate가 누군지 알려주는 과정인데, 쉽게 말하면 "메시지창의 delegate를 내가 할게!" 라고 하는 것이다.

(여기서 '나'는 ViewController를 의미한다.) 

 

 

 

 

3. 굳이 왜 사용하는건가?

1. 범용성을 위해서 

2. 재사용성을 위해서

 

메시지창를 예로 들어보면 아래와 같다.

어디서든 메시지창을 띄우고 눌렀을 때 어떠한 작업을 처리할 수 있게 해달라고 했는데,
그 작업을 메시지 창 내부에서 일을 처리하려고 한다.
만약 이 때 메시지 창을 쓰는 부분마다 처리를 해야하는 내용이 다르다면 문제가 생긴다. 

 

물론 이를 해결할 방법으로는 똑같이 생긴 메시지 박스를 여러개 만들어서 처리를 해줘야한다. 

하지만 이렇게 하면 클래스가 늘어나기 때문에 재사용성이 사라진다.