본문 바로가기
공부/스위프트

[스위프트] 델리게이트 패턴 (delegate)

by 초코팅촉 2023. 8. 6.
728x90

갑자기 목디스크가 와버린 바람에 아무것도 못하고 거의 누워서 지내다 이제 좀 살만해진거 같아서 다시 글을 쓰려고합니다.

아직도 좀 저릿한데 전에 비하면 이정도면 전에비해 정말 너무너무너무너무 괜찮아진거라 행복할 정도.

 

암튼 각설하고,

 

스위프트에는 델리게이트라는 개념이 있다.

최근 계속 ios 네이티브 앱개발을 공부하고 있는데(유데미 안젤라 강의를 듣는중)

델리게이트 패턴과 api에 대한 내용이 나오게 되었다.

앞부분까지는 솔직히 좀 어려울 부분이 크게 없기도 하지만(강의를 볼때 영어 이해하랴 화면보랴 해서 좀 힘들긴 하지만)

드디어 델리게이트 패턴에 도달을 해버린것.

문제는 강의를 어떻게 꾸역꾸역 듣긴했는데 이해가 안되는 상태에서 예시를 작성하려니 죽을맛이다.

 

델리게이트 패턴이 뭔가 중요한건 알겠는데 뭐가 중요한질 모르겠어서 계속 찾아봤다.

다들 델리게이트 패턴이 스위프트에서 매우 중요하다고 하니까 그런갑다 했는데 생각보다 당연히 그럴수밖에 없는거였다.

 

일단 스위프트는 애플꺼다.(이건 너무나도 당연하다.)

그리고 스위프트는 내가 알고있는한 스위프트는 애플제품에서만 쓰인다. 물론 아닐수도 있긴 하겠다만은

이렇다보니 애플에서는 스위프트의 구조를 공개할 생각도 없고 이유도 없다.

그래서 앱을 만들때 각종 오브젝트(예를 들면 텍스트 입력을 받는 TextField나 테이블뷰)의 기능들을 구현해놓지않고 개발자들이 직접 만들어 쓸수 있도록 자유를 주었다.

(9.18 추가된 내용 - 델리게이트 패턴을 사용시에 함수를 구현하거나 해서 데이터를 넘겨주거나 전달받을수도 있고 함수를 실행시킬 수 도있다.)

 

 

이때 그 기능들을 직접 만들기 위해서 존재하는게 델리게이트(delegate)이다.

델리게이트의 뜻은 아래와 같다.

delegate 뜻

무언가를 남에게 위임한다 혹은 대리권자 라는 뜻을 갖는 영어 단어이다.

그래서 스위프트에서도 실제로 위의 뜻대로 쓴다.

앞서 말했던 각종 오브젝트들의 기능들(함수들)을 개발자가 직접 구현하게 위탁하는것이다.

 

하지만 이를 알려면 우선 프로토콜에 대해 알아야한다.

protocol <프로토콜 이름> {
	//안에 들어갈 내용
}

이런식으로 작성하는데 자바에서의 abstract 클래스와 그 기능이 매우 비슷하게 생각되는 친구다.(이건 내 생각.)

갑자기 프로토콜 하니까 어렵게 느껴질 수 있지만 진짜 별거없다.

 

변수나 메소드를 선언하되 기본적인 틀만 만든다 생각하고

변수는 변수명과 자료형

메소드는 필요하다면 입력값 이름과 자료형, 반환형들을 같이 써주고 안에 실제 수행할 코드는 작성하지 않는다.

protocol TestProtocol {

	var testValue: Int
	func testMethod() -> Int
    
}

이런식으로 뭔가 실제 내용은 절대로 적지 않는다.

 

이렇게 만들어진 프로토콜은 델리게이트 패턴에 실제로 쓰이는데

델리게이트 패턴이 프로토콜로 만들어진 (주로)함수들을 갖다 쓰기때문이다.

 

델리게이트 패턴을 이용하려면 우선 

클래스가 상속받는것처럼 프로토콜도 채택해야한다.

그리고 프로토콜을 채택한 클래스에서 구현을 하기때문에 당연히 스스로를 대리자로 위임도 해줘야한다.

 

1. 델리게이트 프로토콜 채택

2. 자신 클래스를 델리게이트(대리자)로 지정

3. 델리게이트 함수를 가져와 실제 구현

 

실제로 텍스트필드 예시를 구현하며 알아보자.

우선 아래처럼 구현한다.

1. 델리게이트 프로토콜 채택

상단에 클래스 선언부분에 UITextFieldDelegate를 추가한다.

class ViewController: UIViewController, UITextFieldDelegate

2. 뷰컨트롤러 클래스를 self로 TextField의 델리게이트(대리자)로 지정한다.

viewDidLoad()메소드 안에 아래 내용을 작성한다.

override func viewDidLoad() {
	super.viewDidLoad()
	textField.delegate = self
}

이렇게 하면 이제 이 뷰컨트롤러 클래스가 대리자가 되어 여기에 메소드를 직접 구현할 수 있다.

 

3. 델리게이트 함수 가져와 구현.

기존에 IBAction으로 buttonPressed() 메소드 구현한 것 밑에

UITextFieldDelegate프로토콜안에 틀만 있는 textFieldShouldReturn()메소드를 구현한다.

이 메소드는 우리가 아이폰 키보드에서 return을 눌렀을때 작동하는 메소드이다.

구현 내용은 간단하게 TextField내용을 TextLabel안에 넣어주는 것으로 하자.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
	textLabel.text = textField.text
	return true
}

 

최종 소스코드(빨간색 네모안이 위에서 추가된 내용이다.)

이렇게 하여 return버튼을 누르나 중간에 버튼을 누르나 같은 작동을 하는 소스코드가 완성됐다.

 

 

+ 추가로 extension을 이용해 기존 클래스 밑에 코드 리팩토링을 해서 따로 밑에 깔끔하게 빼주면 가독성도 좋아지고

아무래도 해당 프로토콜에 속해있는 메소드들을 몰아서 구현할 수 있으니까 유지보수할때도 더 편해진다.

간단한 리팩토링을 거친 소스코드

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

swift - delegate pattern