Delegate Pattern
을 사용해 볼 수 있다.
Teacher
는 cleaningArea 프로퍼티를 가지고 있고,Student
는Teacher
의 cleaningArea 값을 변화시킨다. 해당 과정을delegate pattern
을 통하여 구현해보자.
ViewController
간의 데이터 전달이 아닌, 일반 클래스 간의 데이터 전달의 예를 알아보자. 아래와 같은protocol
을 생성해보자.
// 청소를 시킬 수 있는
protocol CleanOrderable {
var cleaningArea: [String: Bool] { get set }
func notifyTodayCleanArea() -> [String]
}
Teacher
는 CleanOrderable
프로토콜을 채택하였기에 함수의 바디를 작성해주어야된다.class Teacher: CleanOrderable {
var cleaningArea: [String : Bool]
var myClass: String
init(area: [String : Bool], myClass: String) {
self.cleaningArea = area
self.myClass = myClass
}
// 자신(teacher)의 cleaningArea를 던지는 함수
func notifyTodayCleanArea() -> [String] {
return cleaningArea.keys.map { String($0) }
}
}
Student
는 deleagate 변수를 하나 생성해준다.teacher
로 바꿔치기된다.Student
는 Teacher
의 함수를 호출하여 Teacher
의 cleaningArea의 값을 변경한다.class Student {
var delegate: CleanOrderable?
func clean() {
let todayCleanTargetArea = delegate?.notifyTodayCleanArea()
todayCleanTargetArea?.forEach { area in
delegate?.cleaningArea.updateValue(true, forKey: area)
}
}
}
Student
객체의 delegate 변수를 teacher
로 설정해주는 것이다. 그러면 최종적으로 delegate이 teacher
로 바꿔치기되는 것이다!let teacher = Teacher(area: ["복도": false, "교실": false], myClass: "1반")
let student = Student()
student.delegate = teacher
student.clean()
teacher.cleaningArea // ["복도": true, "교실": true]
원래는
tudent
가Teacher
의 cleaningArea를 변경하려면,Student
안에Teacher
를 프로퍼티로 가져서 변경해주면 되지만, 위와 같이delegate pattern
을 통하여 해결을 할 수 있다.
SendViewController
에서 ReceiveViewController
로 데이터 전달을 delegate pattern을 통하여 해보자.
SendViewController
의 textfield에 글을 쓰고 button을 누르면 dismiss가 되면서 textfield에 있는 text가ReceiveviewController
의 label에 나오게 된다.
protocol SendDataDelegate {
func sendData(data: String)
}
SendViewController
에 delegate 변수를 하나 생성해준다. 그리고 delegate?.sendData를 통하여 원하는 데이터를 담아서 보낸다.- 실제로 함수를 실행하는 부분. (delegate는 ReceiveViewController
로 바꿔치기된다.)class SendViewController: UIViewController {
var delegate: SendDataDelegate?
@IBOutlet weak var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func myButtonClicked(_ sender: Any) {
guard let data = myTextField.text else { return }
**delegate?.sendData(data: data)**
dismiss(animated: true, completion: nil)
}
}
ReceiveViewController
에서는 sendViewController
에서 선언한 Delegate이 자신(ReceiveViewController
)임을 선언하고, SendDataDelegate을 채택하여 sendData 함수의 바디를 완성해준다.(실질적인 함수 실행은 SendViewController에서 진행된다.)class ReceiveViewController: UIViewController {
@IBOutlet weak var myLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func plusButtonCliecked(_ sender: Any) {
guard let sendViewController = self.storyboard?.instantiateViewController(withIdentifier: "SendViewController") as? SendViewController else { return }
**sendViewController.delegate = self**
present(sendViewController, animated: true)
}
}
extension ReceiveViewController: **SendDataDelegate** {
func sendData(data: String) {
**myLabel.text = data**
}
}
ViewController A
( 데이터를 전달 받는)
ViewController B
안의 delegate 변수의 위임자가 자신임을 선언해준다.ViewController B
(데이터를 전달하는)