Delegate pattern

도윤·2021년 8월 5일
0

iOS

목록 보기
3/11

https://www.udemy.com/course/ios-13-app-development-bootcamp/learn/lecture/16253668#overview

udemy의 강의를 듣던 중 오늘은 Delegate를 학습하여 내용을 정리하고 복습하고자 합니다!


우선 delegate를 정리하기 앞서 protocol을 알아야 합니다! 강의에서 나온 코드를 토대로 정리하겠습니다.

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

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이 멈추게 되면 실행될 메서드이다.

0개의 댓글