Delegate를 더 쉽게 이해해보기

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.


swift를 공부하면 꼭 알아야 하는 개념중에 하나가 delegate 개념이다.
공부를 하면서 delegate를 쓰긴 쓰는데, 정확하게 이해가 가지 않아 공부하던 찰나 좋은 글이 있어 보고 참고하여 정리해봅니다.

Delegate

delegate를 이해하기 위해서는 우선 프로토콜 개념을 이해해야한다. delegate가 프로토콜로 구현되기 때문이다.

이전에 정리했듯 프로토콜은 단순히 서로간의 약속 이라고 이해하면 쉽다. 구체적인 코드가 짜여져있는 것이 아니라 앞으로 어떤 코드를 짤것인지에 대해 정의해놓는 것이 바로 프로토콜이다. 현실에서의 예로 들자면 ‘선생님’이라는 프로토콜이 있다고 생각해보자. 선생님 프로토콜은 과목명, 담당 수업, 가르치는 행위, 숙제를 행위 등 여러가지의 특징과 기능을 가지고 있을 것이다. 각각의 선생님들은 각자가 가진 선생님 프로토콜을 준수해야한다. 중요한건 이 선생님 프로토콜 안에는 선생님으로서 해야할 행위에 대한 정의만 해놓았지 구체적인 행위의 구현을 하고 있지 않다는 것이다.

애플측에서는 모든 경우의 수를 생각해 구현해내기 힘드니 개발자는 함수 프로토타입을 가지고 자신이 원하는 방향으로 구현만 하면 된다. 즉, 선생님이라는 프로토콜을 채택한 곳에서 구체적인 코드를 구현해내면 되는 것이다. 즉, 프로토콜은 단순히 서로간의 지켜야할 규약 으로 이해하면 쉽다.

Delegate: [명사] 대표(자), 사절, 위임, 대리(자)
[동사] (권한, 업무 등을) 위임하다, (대표를) 선정하다

이전 정리한 글에서도 썼듯 delegate의 사전적의미는 위와 같다.

즉, 내가 해야할 일을 swift가 해서 준다! 정도로 이해하면 조금 쉬워질 것 같은데 swift에서 버튼이나 텍스트필드, 레이블 등 각각의 객체들은 고유의 특징을 가지고 있다. 버튼을 누르면 동작을 한다든지, 글자를 입력할 수 있도록 해주는 것과 같은 특징말이다. 이 delegate pattern은 쉽게 말해 객체 지향 프로그래밍에서 하나의 객체가 모든일을 처리하는 것이 아니라 처리해야할 일 중 일부를 다른 객체에 넘기는 것 을 뜻한다.

더 어렵게 느껴지는 것 같다.

아래는 간단한 UITextFieldDelegate 예제이다.
TextField안에 글자를 쓰고 버튼을 누르면 라벨에 사용자가 쓴 글이 옮겨진다.

  1. Main.Storyboard에 text field, button, label을 하나씩 만들어준다.
  2. 버튼에 대한 액션을 지정해준다.
class ViewController: UIViewController {
  @IBOutlet weak var enteredLabel: UILabel!
  @IBOutlet weak var textField: UITextField!

  @IBAction func buttonClicked(_ sender: Any) {
    enteredLabel.text = textField.text;
  }
}

위 액션의 의미는 말그래도 레이블의 텍스트를 내가 현재 쓴 textField 안의 값으로 써준다라는 의미이다.
textField에 원하는 글을 작성하고 버튼을 누르면 내가 작성한 글 그대로 레이블에 들어가게 될 것이다.

이제 delegate를 써보자. 가장 먼저 해야할 일은 채택작업 이다.

class ViewController: UIViewController, UITextFieldDelegate {
  @IBOutlet weak var enteredLabel: UILabel!
  @IBOutlet weak var textField: UITextField!
}
  1. ViewController에 UITextFieldDelegate를 채택함으로써 해당 프로토콜을 채택해준다.
  2. 이전에 만들었던 IBAction을 지우고 위임자가 누군지 선언해준다.
class ViewController: UIViewController, UITextFieldDelegate {
  @IBOutlet weak var enteredLabel: UILabel!
  @IBOutlet weak var textField: UITextField!

  override func viewDidLoad() {
    super.viewDidLoad()
    textField.delegate = self
  }
}

textField.delegate = self는 결국 윔지가 누군지 알려주는 과정이며 textField의 위임자는 self 즉, ViewController임을 의미한다. 즉 ViewController의 입장에서 TextField의 변화가 감지되면(이벤트가 발생하면) 해당 이벤트를 프로토콜에 따라 응답을 주겠다는 것을 뜻한다.

  1. 그리고 추가적으로 @IBAction를 대신할 함수를 만들어 준다.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  enteredLabel.text = textField.text
  return true
}

textFieldShouldReturn 함수는 UITextFieldDelegate안에 정의되어있는 함수이다. 해당 함수를 UITextFieldDelegate에서 불러와 하고싶은 일만 구현 하면 된다. 함수의 이름으로도 유추할 수 있듯 TextField에 사용자가 어떤 행위를 하고 그 값이 리턴될 것이다 라는 의미이다. 실제 실행해보면 같은 결과가 나타날 것이다.