티스토리 뷰
728x90
타입으로서의 프로토콜 (Protocols as Types)
프로토콜은 기능구현을 하지 않습니다. (선언만 할 뿐)
프로토콜을 타입으로 사용할 수 있습니다.
다른 타입이 허용되는 여러 곳에서 다음과 같은 프로토콜을 사용할 수 있습니다.
- 함수, 메서드 또는 이니셜라이저에서의 매개변수 타입 또는 리턴타입
- 상수, 변수 또는 프로퍼티로서의 타입
- 배열, 사전, 다른 컨테이너의 항목으로서의 타입
타입이기 때문에 네이밍은 첫번째 문자를 대문자로 해줍니다.
ex) TestType
예제로 바로 봐봅시다
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
}
}
class Dice { // <- 채택 안함
let sides: Int
let generator: RandomNumberGenerator // 타입지정
init(
sides: Int,
generator: RandomNumberGenerator
) {
self.sides = sides
self.generator = generator
}
func roll() -> Int {
return Int(generator.random() * Double(sides)) + 1
}
}
var d6 = Dice(sides: 6, generator: LinearCongruentialGenerator())
for _ in 1...5 {
print("Random dice roll is \(d6.roll())")
}
여기선 채택을 해주지 않고 generator라는 상수에 RandomNumberGenerator를 타입으로 지정해줬습니다.
그리고 Dice class 안에 sides, generator의 초기값이 없어 init으로 초기값을 지정해주고,
generator는 RandomNumberGenerator 타입이기 때문에 .(dot 문법)으로 random()에 접근할 수 있게 됩니다.
위임 (Delegation)
Delegate 패턴을 공부하면서 처음 접하게 됐던게 Protocol이었는데요.
다시한번 정리해보겠습니다.
Delegation은 class나 struct가 책임을 일부 다른 타입의 인스턴스로 전달 할 수 있게하는 디자인 패턴 입니다.
대표적으로 많이 사용하는 예시로 다시 설명하자면,
데이터를 보낼 쪽에서 프로토콜을 선언하고, delegate를 선언합니다.
// DetailVC
// 1. 프로토콜 선언
protocol CountDelegate: AnyObject {
func plusCount(count: Int)
}
class DetailViewController: UIViewController {
weak var delegate: CountDelegate? // 2. delegate 선언
var count: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
print(self)
}
@IBAction func tappedButton(_ sender: UIButton) {
count += 1
delegate?.plusCount(count: count)
}
}
데이터를 받는 쪽에서 해당 프로토콜을 채택하면, 프로토콜 내용(메서드, 프로퍼티)을 필수로 갖게 합니다.
해당 메서드, 프로퍼티를 통해 두번째 뷰 (DetailVC)로 부터 데이터를 받을 수 있습니다.
// MainVC
class MainViewController: UIViewController {
@IBOutlet weak var buttonTappedCountLabel: UILabel!
@IBOutlet weak var countLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let detailVC = segue.destination as? DetailViewController else { return }
detailVC.delegate = self // 1-2. ⭐️ 까먹지말고 delegate 위임해 줄 곳을 지정해주자
print("detailVC:\(detailVC)")
}
}
extension MainViewController: CountDelegate { // 1. 프로토콜 채택
func plusCount(count: Int) { // 2. 프로토콜 채택으로 필수 메서드 plusCount(count:) 구현해야함
countLabel.text = "\(count)" // 3. 두번째뷰 (DetailVC)의 데이터를 가져올 수 있음
}
}
여기까지 !
다음엔 protocol extension에 대해 정리해 보겠습니다!!
728x90
'iOS' 카테고리의 다른 글
[Swift] MVVM - 데이터바인딩 databinding(with Observable) (0) | 2022.08.19 |
---|---|
[Swift] Protocol(프로토콜) - protocol extension(프로토콜 확장) (0) | 2022.08.12 |
[iOS] Responder Chain, FirstResponder (0) | 2022.07.17 |
[Swift] ~= 연산자 (0) | 2022.07.13 |
[iOS] Unit Test (0) | 2022.07.10 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- swift programmers
- Swift final
- Swift ModernRIBs
- Class
- swift protocol
- CS 네트워크
- Swift 내림차순
- Swift 알고리즘
- RIBs tutorial
- 2023년 회고
- swift (programmers)
- Swift
- Swift joined
- Swift joined()
- swift property
- Swift RIBs
- Swift 프로퍼티
- iOS error
- Swift inout
- Combine: Asynchronous Programming with Swift
- Swift 프로그래머스
- swift 고차함수
- ios
- Swift Leetcode
- Swift init
- Swift Error Handling
- RTCCameraVideoCapturer
- 원티드 프리온보딩
- removeLast()
- swift reduce
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함