iOS/MacOS 앱을 만들다 보면, 객체 지향형 언어를 많이 다루어 본 사람들도 처음 보는 것이 있다.
바로 Protocol 과 Delegate 이다.
나의 경우는 직전에 WKWebview를 사용하는 Hybrid 앱 개발을 할 때 firebase FCM을 이용하면서, 직접 정의한 push 알림을 구현하기 위해서 AppDelegate.swift를 심도 있게 다루어야 했지만, Delegate가 무엇인지 이해하지 못한채로 작업을 시작했었기 때문에 정말 오래 걸렸던 경험이 있다.
Delegate를 이용하기 위해서는 먼저 Protocol을 이해해야 한다. 먼저 Protocol을 설명한 후,
Delegate는 다음 장에서 설명하도록 하겠다.
1. 그럼 Protocol이 뭐야?
구글링을 해보면 많은 사람들이 Protocol을 규약 혹은 청사진이라고 설명한다. 나는 도저히 이게 와닿지 않았었다. 내가 잘 아는 규약은 HTTP Protocol 밖에 없는데, 우리가 알고싶은 Swift의 Protocol 개념을 이해하는데에는 그렇게 도움이 되지 못했다. 또한 청사진은 Class를 통해 이미 구현하고 있지 않는가.
조금 더 이해를 돕기 위해서, 나는 Protocol을 "필수사항 부여" 로 정의하겠다.
우리가 개발자로서 회원가입 기능을 만들 때를 생각해보자.
우리는 회원가입 기능을 구현하기 위해, 회원가입 form을 만들었다.
여기서 선택사항은 Optional Protocol 이라는 조금 다른 개념이기 때문에, 제외하고 필수사항만 보겠다.
어떤 사이트에서든지 우리는 회원 등록을 원할히 진행하기 위해, 반드시 입력받아야 하는 항목이 있다. 바로 ID와 PW이다.
Protocol은 이러한 필수조건을 지키기 위해서 존재한다.
즉, 회원가입 form 이라는 프로토콜을 따르면, 반드시 ID와 PW를 입력받아야 하는 것이다!!!
이 회원가입form Protocol을 코드로 구현하면 다음과 같다.
먼저 코드를 읽기 전에, 생소할 수 있는 var userNumber: Int { get set } 이 부분은 property로서 getter와 setter가 있는 property를 의미한다.
경우에 따라 get 만 가질 수도 있고 set도 가질 수 있다.
protocol SignUpForm {
// property
var userNumber: Int { get set }
// method
func setID()
func setPW()
}
class NaverSignUp: SignUpForm {
var userNumber: Int {
get {
return userNumber
}
set {
// userNumber을 set하는 작업
}
}
func setID() {
print("Naver에서 사용할 ID를 입력하세요")
// Naver에서 사용할 ID를 입력받는 코드
}
func setPW() {
print("Naver에서 사용할 PW를 입력하세요")
// Naver에서 사용할 PW를 입력받는 코드
}
func setAge() {
print("나이를 입력하세요")
// 나이를 입력받는 코드
}
}
class OKKYSignUp: SignUpForm {
var userNumber: Int {
get {
return userNumber
}
set {
// userNumber을 set하는 연산
}
}
func setID() {
print("Okky에서 사용할 ID를 입력하세요")
// Okky에서 사용할 ID 입력받는 코드
}
func setPW() {
print("Okky에서 사용할 PW를 입력하세요")
// Okky에서 사용할 PW를 입력받는 코드
}
func setJob() {
print("직업을 입력하세요")
// 직업을 입력받는 코드
}
}
코드를 살펴보자. SignUpForm Protocol은 이 Protocol을 채택한 객체로 하여금 반드시 userNumber라는 프로퍼티를 가지도록 하고, ID와 PW를 입력받도록 한다.
NaverSignUP과 OKKYSignUp 모두 property userNumber과 method getID()와 getPW() 을 필수로 가져야 하고, 이에 대해 각자의 상황에 맞추어서 구현한다.
다른 함수는 있어도 그만, 없어도 그만이다.
이제 Protocol이 무엇인지는 이해가 갈 것이다.
2. 그래서 Swift에서 Protocol을 어떻게 사용할 수 있는데?
Protocol은 다음과 같이 선언한다.
protocol [Protocol 이름] {
// property는 gettable, settable 여부를 명시한다.
// ex)
// var 이프로퍼티: String { get }
// var 저프로퍼티: Int { get set }
// 프로토콜에서는 직접적인 구현을 하는 것이 아니라 구현해야 할 목록만 제시한다.
// ex)
// func 이걸구현해주세요()
// func 저걸구현해주세요()
}
그리고 Protocol은 다음과 같이 채택한다.
struct IamStruct: protocolA {
}
Class의 경우 다른 Class에서 상속을 받게 된다면, 상속 받는 Class를 먼저 적고, Protocol은 나중에 적는다.
class IamClass: ClassA, ProtocolA, ProtocolB {
}
3. Protocol을 누가 사용할 수 있어?
Class와 Struct 외에도 enum은 Protocol을 채택하여, Protocol이 요구하는 Method를 구현할 수 있다.
즉, Method(클래스 함수)를 다룰 수 있다.
기본적으로 Protocol은 그 자체가 하나의 타입이다.
그렇기 때문에 다음과 같이 타입으로서 사용할 수 있다.
함수, 메소드, 이니셜라이저의 파라미터 타입 혹은 리턴 타입
상수, 변수, 프로퍼티의 타입
배열, 딕셔너리의 원소타입
'iOS 개발 > Swift' 카테고리의 다른 글
[ARC] 성능을 위해 unowned를 꼭 써야할까? (0) | 2023.02.03 |
---|---|
[ARC] Lazy 변수 클로저에서 Unowned 캡처가 항상 안전할까? (0) | 2023.02.02 |
[Concurrency] Semaphore로 비동기적 이벤트를 동기적으로 발생시키기 (0) | 2023.01.20 |
[ARC] 약한참조(Weak, Unowned)에 대해서 (0) | 2022.11.06 |
[Swift] 지정한 For-Loop 탈출하기 (0) | 2022.10.03 |
[Swift] Stride 함수를 사용하자 (0) | 2022.10.02 |
[Swift] appDelegate 참조 안전하게 하기 (0) | 2021.11.10 |
[Swift] lazy 변수란? - 애플개발자 문서가 수정됐다! (0) | 2021.09.06 |