7. 프로토콜(Protocol)
- Swift의 프로토콜은 인터페이스(Interface) 역할을 수행하며 특정 기능에 대한 청사진(Blueprint)을 정의한다.
- 프로토콜을
채택(Adopt) 한 타입(구조체, 클래스, 열거형)은 해당 프로토콜에서 요구하는 속성과 메서드를 반드시 구현해야 한다.
- 프로토콜의 핵심 개념 3가지
- 규약 정의 : 프로토콜은 특정 메서드, 속성, 연산자 등을 정의한다.
- 구현 강제 : 프로토콜을 채택한 타입은 반드시 규악을 준수해야 한다.
- 다형성 지원 : 하나의 프로토콜로 여러 타입을 동일하게 다룰 수 있다.
- 프로토콜의 특징
| 특징 | 설명 |
|---|
| 메서드 요구 | 특정 메서드를 요구할 수 있음 |
| 속성 요구 | 특정 속성(프로퍼티)을 요구할 수 있음 |
| 다중 채택 가능 | 하나의 타입이 여러 프로토콜을 동시에 채택 가능 |
| 확장(Extension) | 프로토콜에 기본 구현 제공 가능 |
- 프로토콜 정의 및 채택(사용법)
protocol Driveable {
func speedDown(with speed: Int) -> Int
}
struct KIA: Driveable {
func speedDown(with speed: Int) -> Int {
print("속도가 줄어듭니다.")
return speed - 5
}
}
7-1. 프로토콜을 활용한 다형성(Polymorphism)
7.2 프로토콜 확장(Protocol Extension)
- 객체지향의 오버라이드(Overried)와 같은 개념이다.
- 정의된 프로토콜에 추가적인 메소드 구현을 진행할 수 있다.
protocol Driveable {
func speedDown(with speed: Int) -> Int
}
extension Driveable {
func stop() {
print("차량이 멈춥니다.")
}
}
let cars: [Driveable] = [KIA(), Hyundai()]
cars.first?.stop()
Tip. SwiftUI의 Identifiable 프로토콜
- SwiftUI의
ForEach 는 각 항목을 고유하게 구분하기 위하여 Identifiable 프로토콜을 요구한다.
- 컬렉션의 각 항목을 식별하여 뷰가 효율적으로 업데이트 되도록 하는 역할을 수행한다.
- 💡
React 에서 반복되는 컴포넌트의 Key 가 고유한 식별자로 사용되는 것과 같은 기능이다.
- SwiftUI에서 Identifiable 프로토콜의 역할은 아래와 같다.
- 각 항목에 고유한 식별자(id)를 제공한다.
- SwiftUI의
ForEach 가 항목을 추적하고 변경 사항을 감지할 수 있도록 돕는다.
- 리렌더링을 최적화하여 항목치 추가,삭제,변경될 때 정확히 어떤 항목이 수정되었는지 빠르게 파악한다.
- Identifiable 프로토콜의 정의
protocol Identifiable {
associatedtype ID: Hashable
var id: ID { get }
}
- 커스텀 프로토콜과 Identifiable 프로토콜을 채택한 코드의 예시
import SwiftUI
protocol Driveable: Identifiable {
func speedDown(with speed: Int) -> Int
}
struct KIA: Driveable {
let id = UUID()
func speedDown(with speed: Int) -> Int {
print("속도가 줄어듭니다.")
return speed - 5
}
}
struct Hyundai: Driveable {
let id = UUID()
func speedDown(with speed: Int) -> Int {
print("속도가 더욱 줄어듭니다.")
return speed - 10
}
}
struct CarListView: View {
let cars: [Driveable] = [KIA(), Hyundai()]
var body: some View {
VStack {
ForEach(cars) { car in
Text("차량 감속 테스트 중")
}
}
}
}
#Preview {
CarListView()
}