TableView나 TextField와 같은 기능을 사용할 때 가끔 tableView.delegate = self 를 적어주지 않아 동작이 안될때가 있었다.
매번 습관적으로 이 코드를 적어주었지만 왜 이걸 적어야 하는지 알아보고자 한다.
델리게이트 패턴이란?
이름 그대로 위임한다 라는 의미이다. 즉 의임자를 갖고 있는 객체가 다른 객체에게 자신의 일을 위임하는 형태의 디자인 패턴으로 객체와 객체간의 대화라고 생각할 수 있다.
class ViewController: UITableViewDelegate {
func tableViewFunction() {
print("tableview 첫번째 함수 실행")
}
// 실행부
let tableView = UITableView()
tableView.delegate = self // self 또는 위임받을 VC 할당 (보통 viewDidLoad에 적거나 스토리보드로 연결)
tableView.reload() // 원하는 부분에서 사용
}
실제 tableView를 사용할 때 위 코드와 같은 부분을 구현해서 사용한다.
하지만 실제로 채택한 프로토콜 부분과 구현부는 따로 존재한다.
protocol UITableViewDelegate {
func tableViewFunction()
}
class UITableView {
var delegate: UITableViewDelegate?
func reload() {
delegate?.reload() // 내부 구현은 알 수 없음
...
}
}
이와 같은 구조로 코드가 짜여있을 것이라고 생각한다. (실제로는 이와 같이 짜여있진 않다.)
tableView에는 delegate라는 변수에 UITableViewDelegate()가 저장되어 있어 ViewController에서 delegate를 자신의 VC로 저장해야 이 부분을 실행할 수 있다.
따라서 위 UITableView 클래스의 delegate에 할당한 나의 ViewController가 전달되어 우리가 함수를 사용하는 것이다.
추가적으로 두번째화면에서 첫번째 화면으로 데이터를 전달하는 등 어떤 행동을 하고 싶을때 이와 같은 패턴을 사용할 수 있다.
protocol ReloadDelegate {
func reload()
}
class FirstVC: ReloadDelegate {
func reload() {
print("start reload")
}
// 실행부
let secondVC = SecondVC() // 변수 선언
secoondVC.delegate = self // viewDidLoad에 적어줌
secondVC.doSomething() // 원하는 부분에서 이와같이 함수 사용 가능
}
class SecondVC {
var delegate: ReloadDelegate?
func doSomething() {
delegate?.reload()
}
}
위 예제는 SecondVC의 클래스에서 doSomething 함수의 delegate?.reload() 가 실행되었을 때 FirstVC의 reload부분이 실행되는 예제이다.
tableView를 사용할 때와 비슷하지만 조금 다른 부분은 SecondVC에 구현한 부분과 같이 delegate의 실제 구현 부분을 직접 구현해야 한다는 차이가 있다. (tableView는 구체적인 구현은 공개되어 있지 않고 사용만 가능하다.)
위 예제는 두번째 화면에서 첫번째 화면을 reload()하는 예제였지만, 네트워크 통신의 성공/실패 여부에 따른 함수 실행, 두번째 화면에서 첫번째 화면으로 돌아간 후 바로 또 다른 세번째 화면을 나타내어주는 등 .. 과 같은 예제로 다양하게 사용 가능하다.
화면과의 전환에서 자주 사용하긴 했는데, class간에도 사용할 수 있을 것 같다.
그렇다면 왜 프로토콜을 사용할 수 밖에 없을까?
뷰 컨트롤러에게 상황에 대한 판단(동작)을 위임이 가능하다.
또한 객체간 쌍방향 커뮤니케이션이 가능해진다. (데이터를 주고 받는 것도 가능) ex) 리턴값에 따라 텍스트 필드는 동작할지 말지 판단
그리고 텍스트필드의 내부 구현을 숨길 수 있다.
이런 이점들로 애플이 프로토콜을 이용한 델리게이트 패턴을 사용하는것 같은 생각이 든다.
'iOS' 카테고리의 다른 글
[iOS] 코드로 화면 구성하기 (0) | 2023.04.20 |
---|---|
[iOS] xcode Vary for Traits (0) | 2023.03.28 |
[iOS] OAuth Login firebase와 연동하면서 알게된 점 (Apple, Google, Email, Kakao) (0) | 2022.12.23 |
[iOS] 동시성과 관련된 문제 (Concurrency Problems) (0) | 2022.12.16 |
[iOS] 디스패치 그룹(Dispatch Group) (0) | 2022.12.13 |