안녕하세요, iOS 개발하는 루피입니다.
저번 시간에는 공식문서를 의역해보고 정리해 봤다면, 오늘은 Delegate 패턴을 직접 구현해 사용해 보고 정리하는 시간을 가져보려 합니다.
바로 시작하겠습니다.
Delegate 패턴을 왜 사용하는가?
Delegate 패턴을 왜 사용할까요? 일단 Delegate 패턴이 무엇인가? 에 대한 답변을 먼저 찾아보겠습니다!
Delegate 패턴 쉽게 위임자 패턴입니다. 무슨 말이냐고요?? 조금 더 쉽게 말해 보겠습니다!!
내가 해야 하는 일이 있어요 ㅠㅠ 아 근데 내가 하기 너무 귀찮단 말입니다. 그러던 중 한 녀석이 보이는 거죠. 그러고 저는 말합니다. 아니 외칩니다. 야 너가 해!! 그냥 깡패가 따로 없나요??? ㅋㅋㅋㅋㅋㅋㅋ
이런 식으로 다른 객체에게 역할을 위임한다고 생각하시면 될 거 같습니다. 그리고 그 위임자를 만드는 방식은 Delegate를 채택하는 방법이 될 것입니다.
자 그러면 Delegate 패턴이 뭔지 알겠다. 그다음 "이걸 도대체 왜 사용할까?"라는 의문을 해결해 보겠습니다.
그 이유는 바로 편하기 때문입니다.
왜 편해지는지 설명해 보겠습니다.
Delegate 패턴을 사용할 때는 프로토콜을 사용합니다. 그리고 그 안에는 이 프로토콜을 채택한 객체들이 수행해야 하는 메서드들을 명시해 둡니다. 물론 구체적인 구현을 프로토콜 안에 하지는 않지만, 결국이 프로토콜을 채택한 객체들은 명시된 메서드를 실행해야 하는 약속이 생기게 됩니다.
아니 그래서 뭐가 편한 건데???
바로 재사용성이 월등히 올라가지 않을까요? 다시 한번 예시를 한번 들어보겠습니다.
예시를 한번 군대로 들어보겠습니다. 왜냐면 재밌을 거 같아 들어보겠습니다! 기술 블로그에 군대 얘기 신박하잖아요.
저는 생활관에서 제일 계급이 높은 선임입니다. 근데 계급이 올라갈수록 할 수 있는 것들이 많아지기 때문에 해야 하는 일들이 많아진답니다. 근데 저는 몸이 하나고 하루에 사용할 수 있는 시간도 체력도 정해져 있죠? 그래서 제가 결정을 내렸습니다.
아 애들한테 좀 업무를 분배해야겠다. 저는 조금 더 기술이 요구되는 정밀한 작업을 하고 내 밑으로는 단순 노동으로도 할 수 있는 작업을 분배하려 합니다. 그러면 저는 후임들에게 다 찾아가서 부탁해야 할까요? 물론 가능합니다. 근데 많은 시간과 노동이 들겠죠. 한 명 한 명 다 찾아가서 얘기하려면 많이 힘들 겁니다... 어떤 걸 해야 하고 그걸 하려면 뭘 어떻게 해야 하고 뭘 가져가야 하고 한 명씩 다 찾아가서 말해주기가 너무 힘들죠. 그래서는 하나의 쪽지에 내용을 적어서 후임들이 돌려보고 일을 할 수 있도록 행동했습니다.
예시가 좀 그런데 이해가 가시나요? 여기서 저는 저의 역할을 후임에게 위임을 하는 것이고, 후임들 즉, 객체들을 다 찾아가서 일일이 메서드를 구현하기 힘들기 때문에 해야 하는 일들을 프로토콜이라는 메모장에 적어놓고, 이를 채택한 객체들이 해당 메서드를 필수적으로 실행하도록 만든 겁니다.
Delegate 패턴 직접 구현해서 확인해 보기
2개의 VC를 만들 겁니다. 그리고 첫 번째 VC에서 Start 버튼을 누르면 두 번째 VC로 넘어갑니다.
두 번째 VC에는 2개의 버튼이 있습니다. Sad와 Happy 버튼이있는데요. 둘중 하나의 버튼을 누르면 자동으로 첫번째 VC로 돌아가고 empty Label이 변경 되게 됩니다.
이 과정을 저는 첫번째 VC를 두번째 VC의 위임자로 채택하여 진행해 보겠습니다.
Protocol
import Foundation
protocol SecondViewDelegate: AnyObject {
func IsLableChange(_ viewController: SecondViewController, emotion: String)
}
첫 번째 VC
import UIKit
class FirstViewController: UIViewController {
var mainView = FirstView()
override func viewDidLoad() {
super.viewDidLoad()
self.view = mainView
mainView.buttonAction = { [weak self] in
self?.navigateToSecondViewController()
}
}
private func navigateToSecondViewController() {
let secondVC = SecondViewController()
secondVC.delegate = self
self.navigationController?.pushViewController(secondVC, animated: true)
}
}
extension FirstViewController : SecondViewDelegate {
func IsLableChange(_ viewController: SecondViewController, emotion: String) {
mainView.emotionLabel.text = "\(emotion)"
self.navigationController?.popViewController(animated: true)
}
}
보면 Start 버튼을 터치 시 SecondVC의 위임자로 FirstVC를 지정합니다.
그리고 Extension을 이용해 채택된 Delegate의 메서드를 구현합니다.
두 번째 VC
import UIKit
class SecondViewController: UIViewController {
var mainview = SecondView()
weak var delegate: SecondViewDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.view = mainview
mainview.happyBtnTap = { [weak self] in
self?.happy()
}
mainview.sadBtnTap = { [weak self] in
self?.sad()
}
}
func happy(){
self.delegate?.IsLableChange(self, emotion: "happy")
}
func sad(){
self.delegate?.IsLableChange(self, emotion: "sad")
}
}
감정 버튼을 클릭 시 SecondVC의 위임자 즉 FirstVC를 이용해 함수를 실행합니다.
이런 식으로 구현을 하게 된다면, 결론 적으로 SecondVC는 메서드가 어떻게 구현되는지 세세하게 알 필요 없이 단순히 메서드를 호출하기만 하면 되기 때문에 두 VC 간 결합도가 낮아지는 것을 확인할 수 있습니다. 와우 대박입니다.
오늘도 화이팅입니다!
'iOS > Swift' 카테고리의 다른 글
[Swift] ARC 2/3 (0) | 2025.01.28 |
---|---|
[Swift] ARC 1/3 (0) | 2025.01.28 |
[Swift] Delegate를 사용해 객체의 동작을 커스텀하기 (0) | 2025.01.16 |
[Swift] 스위프트에서 KVO 사용하기 (0) | 2025.01.16 |
[Swift] Singleton(싱글톤)을 이용해 공유 자원 관리 (0) | 2025.01.15 |