프로토콜이란, 선언된 프로퍼티, 메소드, 기타 요구사항 등을 직접 구현하지 않고 특정 역할을 수행하고자, 조건만 제시한 규약입니다.
Protocol를 이용하여 권한을 위임하고 일을 처리하는 방식의 디자인 패턴입니다.
다시말해 delegate pattern은 클래스나 구조체의 인스턴스에 특정 행위에 대한 책임을 다른 타입의 인스턴스에게 넘기는 방식입니다.
( 하나의 특정 객체가 모든일을 처리하는 것이 아닌, 처리해야할 일 중 일부 작업을 다른 객체에 넘기는 것을 의미합니다. )
그럼, 어떻게 권한을 위임할까? 아마도 같은 프로토콜을 채택한 클래스에게 권한을 위임해주는 것 같습니다.
protocol ADelegate {
}
class A {
var delegate: ADelegate
}
class B: ADelegate {
a.delegate = self
}
View Controller를 보면, TableView의 특정 셀에 있는 여러 개의 버튼 중 특정 버튼을 눌렀을 경우에 해야할 일을 View Controller로 넘겨주기 위해서 Delegate 패턴을 사용합니다.
TableViewCell이 선택되었을 경우 호출하는 기능은 TableView Delegate에서 기본적으로 처리하고 있지만, 내부의 특정 버튼에대한 이벤트는 처리할 수 없습니다.
이와 같은 경우엔 Custom Delegate를 만들어서 구현이 가능합니다.
protocol ResultTableViewButtonDelegate {
func didSelectPositionButton(item: ResultStore?)
}
class ViewController: UIViewController {
}
extension ViewController: ResultTableViewButtonDelegate {
func didSelectPositionButton(item: ResultStore?) {
let storyboard = self.storyboard
let positionVC = storyboard?.instantiateViewController(withIdentifier: "positionVC") as! PositionViewController
positionVC.item = item
self.navigationController?.pushViewController(positionVC, animated: true)
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "resultStoreCell", for: indexPath) as! ResultTableViewCell
cell.item = self.presenter.getStoreFromList(index: indexPath.row)
cell.selectionStyle = .none
cell.delegate = self return cell
}
...
}
class ResultTableViewCell: UITableViewCell {
...
var item: ResultStore? {
didSet {
...
}
}
var delegate: ResultTableViewButtonDelegate?
@IBAction func onClickPositionBtn(_ sender: UIButton) {
delegate?.didSelectPositionButton(item: self.item) }
...
}
TableView Cell을 정의할때 delegate를 할당해줍니다.
cell.delegate = self
TableView Cell안에 있는 UIButton의 클릭 이벤트 발생 시 IBAction 함수가 호출됩니다. (onClickPositionBtn)
각 TableView Cell은 item을 가지고 있으며 이 item을 delegate method의 인자값으로 넘겨줍니다.
delegate?.didSelectPositionButton(item: self.item)
ViewController에서 구현되어 있는 delegate 함수가 호출되며 해당 함수 안에서 받아온 데이터로 작업을 수행합니다.