반응형
선택적 요구 사항 Optional Requirements
- @objc -> Objective - C에서도 사용가능하도록 하는 키워드
- Optional 은 멤버를 선택적 멤버로 변경하게 하는 것이다
- 프로토콜 키워드 앞에 @objc 추가, 멤버 선언 앞에도 추가해야지 사용가능하며, 멤버 선언 시 optional키워드를 추가해야한다
- AnyObject를 자동 상속 -> 클래스 전용 프로토콜이 된다
@objc protocol 프로토콜 이름 {
@objc optional 요구사항들
}
프로토콜 확장 Protocol Extension
- 프로토콜 역시 type이기 때문에, extension으로 확장가능
- 프로토콜 확장시, 프로토콜을 채용한 모든 type에 추가
- Extension 사용시, 프로토콜에 구현을 추가 -> 프로토콜을 채용한 type에 사실상 구현을 추가하는 것
- type에서 구현한 함수가 우선순위가 높다.
protocol Figure {
func draw()
}
extension Figure {
func draw() {
print("draw figure")
}
}
Equatable protocol ==
- 가장 기본적인 프로토콜, 컴파일러가 자동으로 구현해줌
- 값의 동일성을 비교할 수 있는 프로토콜
- == 비교 연산자
- 구조체 끼리, 비교 하고싶으면 Equatable을 채택만 하면됨
- 클래스에서 사용하고 싶으면, 직접 구현해야함
- 열거형의 경우 자동으로 구현 , 채택도 필요X
- 인스턴스 끼리 정확하게 비교해야함
struct Human: Equatable {
var name = ""
var age = 0
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.name == rhs.name
}
}
let human1 = Human.init()
let human2 = Human.init(name: "", age: 19)
human1 == human2 // true
class Human {
var name = ""
var age = 0
}
extension Human: Equatable {
static func == (lhs: Human, rhs: Human) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
}
let human1 = Human.init()
let human2 = Human.init()
human2.age = 10
human1 == human2 // false
enum Gender: Equatable {
case male(name: String)
}
let man = Gender.male(name: "so")
let man2 = Gender.male(name: "deul")
man == man2 // false
Hashable protocol
- 딕셔너리 키 타입과 셋 요소 타입이 구현해야 하는 Hashable 프로토콜
- Hashable 프로토콜을 채택하는 타입은 모두 값을 정수인 해시값으로 표현할 수 있다.
- Hashable 프로토콜을 채택하는 커스텀 타입의 저장 프로퍼티가 모두 Hashable 프로토콜을 채택하고 있다면, 별다른 구현없이 Hashable 프로토콜을 채택하는 것 만으로 Hashable한 동작을 제공한다.
- Hashable은 Equatable을 채택
- 해시 충돌이 발생하는 경우를 알기 위해서는 두 인스턴스가 값이 일치하는 확인해야하기 때문에 Equatable 프로토콜을 채택해야한다
- 해시 충돌 -> Hash 값을 생성하는 built in 메소드인 hasher(_:) 가 서로 다른 값에 대해 동일한 Hash 값을 생성
- 클래스의 경우 Hashable 프로토콜을 채택해야 하는 자료형에서 사용할 수 있다.
- 구조체의 경우 채택만 하면됨
- 열거형의 경우, 연관값이 있으면 채택, 없으면 자동으로 구현됨
struct Human: Hashable {
let name: String
let age: Int
}
let myDict: [Human: Int] = [:]
class Human {
let name = "Sodeul"
let age = 28
}
extension Human: Hashable {
static func == (lhs: Human, rhs: Human) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(age)
}
}
let myDict: [Human: Int] = [:]
enum Gender: Hashable {
case male(age: Int)
}
let myDict: [Gender: Int] = [:]
Comparable protocol >, >=, <=, <
- 값의 크기와 순서를 비교할 때 필요한 Comparable 프로토콜
- string의 경우, 유니코드를 기준으로 비교
- Equtable을 채택
- 구조체의 경우, 채택과 구현까지 해야함
- 클래스의 경우도 채택과 구현
- 열거형의 경우도, Swift 5.3 미만의 경우 Comparable을 채택 & 구현
- 연관값이 있다면 5.3이상의 경우 채택으로만 가능
- 없다면, 채택, 구현 다해야함
struct Person: Comparable {
static func < (lhs: Person, rhs: Person) -> Bool {
return lhs.age < rhs.age
}
var name = ""
var age = 0
}
let sodeul = Person.init(name: "sodeul", age: 28)
let clone = Person.init(name: "clone", age: 30)
sodeul = clone // false
sodeul <= clone // true
class Person: Comparable {
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name && lhs.age == rhs.age
}
static func < (lhs: Person, rhs: Person) -> Bool {
return lhs.age < rhs.age
}
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let sodeul = Person.init(name: "sodeul", age: 28)
let clone = Person.init(name: "clone", age: 30)
sodeul > clone // false
sodeul <= clone // true
enum Number: Int, Comparable {
static func < (lhs: Number, rhs: Number) -> Bool {
return lhs.rawValue < rhs.rawValue
}
case one, two, three
}
Number.one > Number.two // false
반응형
'iOS > Swift' 카테고리의 다른 글
[Swift] Concurrency [1] (1) | 2023.10.23 |
---|---|
[Swift] Optional (1) | 2023.10.17 |
[Swift] Protocol 프로토콜 [1] (0) | 2023.09.01 |
[Swift] struct, class, enum (0) | 2023.08.31 |
[Swift] Final 키워드 왜 쓰는 걸까? (0) | 2023.08.06 |