생각하며 읽으면 좋은 질문
Q1. 프로토콜이 무엇일까?
Q2. 프로토콜은 언제 필요할까?
Q3. 프로토콜은 어떻게 사용할까?
프로토콜 구문
protocol Learner {
//protocol definition
}
class someClass: UIViewController, Learner, Service {
// class definition
}
프로토콜 네이밍 규칙
- 프로토콜은 Type이기 때문에 UpperCamelCase로 만들어준다.
- 프로토콜은 개념/역할을 중심으로 네이밍
- 구현체는 구체적인 기능/상황을 중심으로 네이밍
swift 내의 프로토콜 - 구현체 예시
- Collection - Array, Dictionary, Set
- Comparable - Int, Double, String
- Error - enum NetworkError: Error { ... }
ex) Collection
protocol Collection {}
struct Array<Element>: Collection {}
struct Dictionary<Key: Hashable, Value>: Collection {}
struct Set<Element: Hashable>: Collection {}
ex) UserService
protocol UserService {}
struct NetworkUserService: UserService {}
struct MockUserService: UserService {}
struct CachedUserService: UserService {}
프로퍼티 요구사항
{ get set } 작성{ get } 으로 작성protocol LearnerProtocol {
static var generation: Int { get }
var nickname: String { get set }
}
struct Learner: LearnerProtocol {
static let generation = 4
var nickname: String
}
var learner = Learner(nickname: "Jam")
메서드 요구사항
protocol Tappable {
func didTap()
}
struct ButtonHandler: Tappable {
func didTap() {
print("Button tapped!")
}
}
protocol RandomNumberGenerator {
func random() -> Double
}
class LinearCongruentialGenerator: RandomNumberGenerator {
var lastRandom = 42.0
let m = 139968.0
let a = 3877.0
let c = 29573.0
func random() -> Double {
lastRandom = ((lastRandom * a + c)
.truncatingRemainder(dividingBy:m))
return lastRandom / m
}
}
let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())")
// Prints "Here's a random number: 0.3746499199817101"
print("And another one: \(generator.random())")
// Prints "And another one: 0.729023776863283"
변경 메서드 요구사항
- 변경 메서드 사용 조건
- 값 타입(Value Type)이 프로토콜을 채택할 가능성이 있음
- 해당 메서드가 프로퍼티 또는 self를 수정할 예정임
protocol Toggleable {
mutating func toggle()
}
struct Switch: Toggleable {
var isOn: Bool = false
mutating func toggle() {
isOn.toggle()
}
}
var mySwitch = Switch()
print("처음 상태:", mySwitch.isOn) // false
mySwitch.toggle()
print("토글 후 상태:", mySwitch.isOn) // true
초기화 구문 요구사항
protocol SomeProtocol {
init()
}
class SomeSuperClass {
init() {
// initializer implementation
}
}
class SomeSubClass: SomeSuperClass, SomeProtocol {
required override init() {
// initializer implementation
}
}