다른 클래스 및 구조체에 포함할 속성과 함수의 청사진을 만드는 방법. 일관성과 예측가능성이 장점이다.
protocol PersonProtocol {
var name: String { get set }
var job: String { get set }
func getNameAndJob() -> String
}
프로토콜은 단순히 속성과 기능을 정의할 뿐이다.
그 자체로는 아무것도 하지 않고, 논리를 포함하지 않는다.
protocol PersonProtocol {
var name: String { get set }
var job: String { get set }
func getNameAndJob() -> String
}
class CompanyClass: PersonProtocol { ... }
class CompanyClass: PersonProtocol {
var name: String
var job: String
func getNameAndJob() -> String {
return name + ", " + job
}
}
위 CompanyClass는 PersonProtocol을 준수한다.
즉, 해당 PersonProtocol의 모든 속성과 함수는 CompanyClass 내부에서 사용되어야 한다.
struct ProtocolsAsType: View {
var p1: PersonProtocol
var p2: PersonProtocol
var body: some View {
VStack(spacing: 20) {
Text(p1.getNameAndJob())
Text(p2.getNameAndJob())
}
.font(.title)
}
}
프로토콜도 상속이 가능하다.
다만 해당하는 프로토콜들의 요구사항을 모두 구현해줘야 한다.
예를 들어 A프로토콜이 있고 B프로토콜이 있다고 가정해 보자.
B프로토콜이 A프로토콜을 상속받은 상태이고, 나는 B프로토콜을 채택하려고 한다.
그럼 그 B프로토콜을 채택한 곳에서 A프로토콜과 B프로토콜이 요구하는 사항을 모두 구현해줘야 한다는 의미이다.
프로토콜을 통해 Publisher(및 Operator)가 동일한 기능을 가질 수 있으며, 모든 Subscriber도 동일한 기능을 가질 수 있음.
// Publisher(및 Operator)에게는 Subscriber에 연결할 수 있는 수신 기능이 있음.
protocol Publisher {
func receive(subscriber:)
}
// 3가지 Subscriber 수신기능
protocol Subscriber {
func receive(subscription:)
func receive(input:)
func receive(completion:)
}
Subscriber에는 3가지 수신 기능을 하는 함수가 존재
1. func receive(subscription:) : 구독자가 성공적으로 구독한 시기
2. func receive(input:) : 정보를 받는 시기
3. func receive(completion:) : 구독서비스를 종료한 시기
이러한 프로토콜을 사용하면 모든 Publisher, Operator, Subscriber들을 파이프라인처럼 연결할 수 있다.
물론 Combine에서 제공하기 때문에 직접 구현할 필요가 없다.