https://www.udemy.com/course/ios-13-app-development-bootcamp/learn/lecture/16253668#overview
udemy의 강의를 듣던 중 오늘은 Delegate를 학습하여 내용을 정리하고 복습하고자 합니다!
우선 delegate를 정리하기 앞서 protocol을 알아야 합니다! 강의에서 나온 코드를 토대로 정리하겠습니다.
performCPR을 할 수 있다.
protocol AdvancedLifeSupport {
// CPR을 행할 수 있는 능력
func performCPR()
}
이 프로토콜은 자격증을 나타낸다.
이 자격증을 가진(=":AdvancedLifeSupport"를 뒤에 적은) 사람들, 즉 이 프로토콜을 채택한 클래스들은 모두 func performCPR()을 할 수 있다는 의미입니다.
프로토콜은 선언된 함수의 중괄호,코드 내용들을 직접 선언하지 않고, 위 프로토콜을 채택한 클래스나 구조체가 직접 할당해야 한다.
따라서
struct Paramedic: AdvancedLifeSupport {
// 응급상황 때마다 나에게 직접 연락을 해줄 콜센터 직원(=handler 인수) 배정
init(handler: EmergencyCallHandler) {
// 취득자 자신(=self)은 콜센터 직원(=handler 인수)으로부터 언제나 호출을 받는 상황이 된다.
handler.delegate = self
}
func performCPR() {
print("Paramedic Execute CPR.")
}
}
위 처럼 AdvancedLifeSupport를 채택한 Paramedic 구조체들은 모두 프로토콜이 보유한 performCPR()을 수행할 수 있어야 한다.
만약 performCPR()을 선언하지 않으면 오류가 발생하므로 유의해야한다!
Delegate를 한국어로 해석하면 대리자 또는 위임자라고 해석된다.
//응급 상황이 생기면 AdvancedLifeSupport을 채택한 클래스에게 이 상황을 호출한다.
class EmergencyCallHandler {
// 자기 자신을 delegate로 정의하는 클래스나 스트럭트 모두 이 delegate 변수를 프로퍼티로 가져야 한다.
// CPR 자격증 취득자에 한해서만 delegate를 선언할 수 있다.
var delegate: AdvancedLifeSupport?
func medicalEmergency() {
// CPR 가능한 사람은 이 알람을 듣고 CPR을 행해주세요
delegate?.performCPR()
}
}
AdvancedLifeSupport프로토콜 타입으로 delegate 변수가 선언이 되었다.
let emilio = EmergencyCallHandler()
let pete = Paramedic(handler: emilio)
emilio.medicalEmergency()
//Paramedic Execute CPR.
emilio가 medicalEmergency()을 호출하게 되면 delegate인 pete가 performCPR()을 수행하게 되는 코드이다.
class Doctor: AdvancedLifeSupport {
init(handler: EmergencyCallHandler) {
handler.delegate = self
}
func performCPR() {
print("A Doctor perfoms CPR.")
}
func useStethoscope() {
print("Listen to heartbeat.")
}
}
class Surgeon: Doctor {
// 의사 중에서도 외과의사는 CPR을 하며 노래도 부를 수 있는 경지.
override func performCPR() {
super.performCPR()
print("Surgeon even sing a song.")
}
}
let ben = Surgeon(handler: emilio)
// 정리 : emilio가 신고접수를 받으면, CPR 자격증 보유자 모두에게 연락이 간다.
emilio.medicalEmergency()
/*
Can you tell me what happend?
Paramedic Execute CPR.
A Doctor perfoms CPR.
Surgeon even sing a song.
Program ended with exit code: 0
*/
이렇게 예시가 아닌 직접 사용 사례인 UITextFieldDelegate를 살펴보겠다
class MainViewController : UITextFieldDelegate {
@IBOutlet weak var searchTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
searchTextField.delegate = self
}
}
UITextFieldDelegate를 채택한 클래스가 존재할 때 viewDidLoad()메서드 내에서 UITextFieldDelegate를 담당하는 클래스가 MainViewContoller에서 통제되도록 위임되었다.
애플 공식문서를 보게 되면 UITextViewDelegate 프로토콜의 모든 메서드들은 optional타입이라서 반드시 선언할 필요 없이 사용할 필요가 있는 메서드만 사용하면 된다.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
searchTextField.endEditing(true)
print(searchTextField.text!)
return true
}
//키보드에서 입력을 마친 후 Return을 눌렀을 때 발생하는 메서드
//endEditing가 true이면 편집을 마치는 신호를 보내는 메서드이다.
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if textField.text != "" {
return true
} else {
textField.placeholder = "Type Something"
return false
}
}
func textFieldDidEndEditing(_ textField: UITextField{
if let city = searchTextField.text {
weatherManager.fetchWeather(cityName: city)
}
searchTextField.text = ""
}
//Editing이 멈추게 되면 실행될 메서드이다.