-
Swift4 : 프로토콜 1 : #Protocol : #설계 : #요구사항 : #델리게이션 : #델리게이트 패턴 ( 1 / 2 )스위프트: Swift/스위프트: 언어자체: 문법 2018. 9. 7. 18:16
안녕하세요 ! 씩이 입니다!
저는 Swift 와 iOS 를 공부하고 연구하는 학생입니다.
같은 분야를 공부하는 분들에게 조금이라도 도움이 주고 싶어서 공부하는 것들을 공유합니다.
제 3자가 있다고 가정하고 설명하기 때문에 존대를 하지 않는점 이해 부탁드립니다.
공유가 미래 라고 생각합니다.
한국의 모든 개발자분들 존경합니다!
- Swift version : Swift 4.2 Swift 언어
- 참고한 것들
- 씩이 Github
- 자료구조 소스파일 있습니다.
- iOS 관련 자료들, 정보들 정리해 두었습니다.
- 스위프트로 구현한 자료구조 : DataStructures in Swift4
- Swift4 : 연결리스트 (1 / 3) : #LinkedList : #DataStructrue : #자료구조
- Swift4 : 연결리스트 (2 / 3) : #LinkedList : #값 추가하기, push, append : #값 삽입하기,insert
- Swift4 : 연결리스트 (3 / 3) : #LinkedList : #값 제거하기, pop, removeLast, remove(at: )
- [스위프트 : 자료구조] 스택: Stack: 자료구조: DataStructure: 쌓기
- [스위프트 : 자료구조] 스택 : Stack : 프로토콜 지향 스택 구현하기
- [스위프트 : 자료구조] 큐 (1 / 4): Queue: #자료구조: #배열로 구현한 큐: #배열의원리
- [스위프트 : 자료구조] 큐 (2 / 4): Queue: #자료구조: #연결리스트: #더블연결리스트: #DoublyLinkedList
- [스위프트 : 자료구조] 큐 (3 / 4): Queue: #자료구조: #Stack으로 구현: #더블스택: #DoubleStack: #제일좋음
- [스위프트 : 자료구조] 큐 (4 / 4): Queue: #자료구조: #RingBuffer: #링버퍼로 구현한 큐: #고정된배열: #마지막!!
- [스위프트 : 자료구조] 큐: Queue: 프로토콜 지향 큐 구현하기
- 스위프트: 트리: Tree: #자료구조: #깊이우선탐색: #레벨정렬탐색: #검색알고리즘: Swift4
- 스위프트: 이진 탐색 트리(1 / 2): #BinarySearchTree: #자료구조: #배열과 비교: #트리: #탐색: #삽입: #삭제
- 스위프트: 이진 탐색 트리(2 / 2): #BinarySearchTree: #자료구조: #배열과 비교: #트리: #탐색: #삽입: #삭제
- [스위프트 : 자료구조] AVL Tree: 자가 균형 트리: #balance: #트리의 높이: #rotation메소드: #성능오짐
- [스위프트:자료구조] 트라이: Trie: 문자열 찾기: 단어 찾기
- [스위프트:자료구조] Heap: 힙 자료구조 (1 / 2) : Heap 이란?
- [스위프트:자료구조] Heap: 힙 자료구조 (2 / 2) : Heap 구현하기
- 스위프트로 구현한 알고리즘 : Algorithms in Swfit4
- [스위프트 : 알고리즘] 재귀호출 (1 / 6) : recursive: 재귀호출 : 재귀함수: 반복문: 팩토리얼: 거듭제곱: 피보나치: 하노이의 탑: 최대공약수
- [스위프트 : 알고리즘] 재귀 : 팩토리얼 (2 / 6) : factorial: 재귀호출 : 재귀함수: 반복문: 팩토리얼: 거듭제곱: 피보나치: 하노이의 탑: 최대공약수
- [스위프트 : 알고리즘] 재귀 : 거듭제곱 (3 / 6) : Power: 재귀호출 : 재귀함수: 반복문: 팩토리얼: 거듭제곱: 피보나치: 하노이의 탑: 최대공약수
- [스위프트 : 알고리즘] 재귀 : 피보나치 수열(4 / 6) : Fibonacci: 재귀호출 : 재귀함수: 반복문: 팩토리얼: 거듭제곱: 피보나치: 하노이의 탑: 최대공약수
- [스위프트 : 알고리즘] 재귀 : 하노이의 탑 (5 / 6) : Hanoi: 재귀호출: 재귀함수: 반복문: 팩토리얼: 거듭제곱: 피보나치: 하노이의 탑: 최대공약수
- [스위프트 : 알고리즘] 재귀 : 최대공약수 (6 / 6) : GCD: 재귀호출: 재귀함수: 반복문: 팩토리얼: 거듭제곱: 피보나치: 하노이의 탑: 최대공약수
- [스위프트:알고리즘] 이진 탐색[1 / 3]: Binary Search: 이진 탐색이 뭐야?
- [스위프트:알고리즘] 이진 탐색[2 / 3]: Binary Search: 이진 탐색: 반복문, 재귀호출로 구현하기
- [스위프트:알고리즘] 이진 탐색[3 / 3]: Binary Search: 이진 탐색: 프로토콜 지향으로 구현하기
- Swift 주제별 분류
- Swift4 : 제어 전달 명령문( Control Transfer Statement ) : #continue, #break, #return 키워드
- Swift4 : 클래스와 구조체 : #값을 대하는 방식 : #참조타입, 값 타입 : #===
- Swift4 : 프로퍼티 : #Property : #get, set : #willSet, didSet
- Swift4 : 메소드 : #Method : #영향력 범위 : #self : #mutating : #값타입 수정
- Swift4 : 프로토콜 1 : #Protocol : #설계 : #요구사항 : #델리게이트 패턴 전처리 (1 / 2)
- Swift4 : 프로토콜 2 : #델리게이트 패턴 : #델리게이션 (2 / 2)
- Swift4 : 제네릭 : #Generics : #왜필요해? : #where키워드 : #제약사항걸기
- Swift4 : 자동 참조 카운팅 : #Automatic Referece Counting : #ARC :#강한참조 : #Strong Reference Cycle : #메모리 누수
- Swift4 : 클로저: Closure: #표현방식: #왜필요해?: #효율적: #간결성: #생략
- [스위프트 : 기초] 서브스크립트 : Subscript : 지름길
프로토콜 : Protocal ( 1/2 )
- What is Protocal
- 특정 작업이나 기능에 적합한 메소드나 프로퍼티의 요구사항을 정의하는 설계이다. ( 건물을 짓기 전 전체적인 청사진을 그리는 것에 비유되곤 합니다. )
- 클래스나 구조체 혹은 열거형등 특정 타입이 요구사항들이 설계된 프로토콜을 채택하는 방식입니다.
- 프로토콜을 따르는 모든 타입은 해당 프로토콜의 요구사항을 꼭 지켜야 합니다. 그렇지 않으면 컴파일 오류 발생.
- 프로토콜은 iOS 프로그래밍에서 매우 자주 쓰이는( 그래서 매우 중요한!! ) 델리게이트 패턴의 기반이 됩니다.
- 델리게이트 패턴을 알려고 프로토콜을 알아야 하는 정도...
- 델리게이트 패턴의 전처리 과정으로 프로토콜을 설명하는 것입니다. 난해한 설명이 될테니 조금은 가벼운 마음으로 읽으시고 델리게이트 부분부터 빡집중해야 합니다. 그러지 않으면 이해할 수 없을만큼 은근히 복잡합니다!
----------------------------------- 이 아래에 '요구사항' 이라고 표현한 것은 모두 프로토콜 안에 정의된 것들입니다. ------------------------------------- 프로퍼티 요구사항 ( Properties in Protocol )
- 제한의 범위는 ?
- 프로포콜은 프로퍼티가 저장 프로퍼티 인지 연산 프로퍼티 인지를 지정하지 않는다.
- 프로퍼티 이름이나 타입을 지정할 수 있고, get 인지, set 까지 설정 해야하는지 를 지정할 수 있다.
- 예를들어 프로토콜이 get, set 모두 있는 프로퍼티를 요구하면, 저장 프로퍼티나, 읽기전용 프로퍼티를 쓸 수 없다.
- 타입 프로퍼티를 요구하고 싶은 게, static 이든, class 든 프로토콜에선 static 으로 통일한다.
- 아래 예제에는 이러한 것들이 포함됩니다.
- #Protocol 사용법 : #Protocal을 채택한 Class : #원칙을 따르지 않았을 때
1234567891011121314151617protocol FullyNamed { // FullyNamed 프로토콜 : 이 프로토콜을 따르는 타입은 프로콜에 작성한 요구사항을 따라야 한다.var fullName: String { get } // 요구사항}class Starship: FullyNamed { // FullyNmaed 프로토콜을 따르는 클래스 타입의 Starshipvar prefix: String? // prefix 옵셔널 값임. 초기화 시 안받아도 됨을 유의.var name: Stringinit(name: String, prefix: String? = nil) { //초기화로 name, prefix 받음self.name = nameself.prefix = prefix}var fullName: String {//FullyNamed 프로토콜의 요구사항 대로 fullNmae 프로퍼티 정의// fullName 을 정의하지 않으면 컴파일 오류가 발생한다. -> 원칙을 따르지 않으면 오류발생.return (prefix != nil ? prefix! + " " : "") + name}}var ncc1701 = Starship(name: "Enterprise", prefix: "USS")// ncc1701.fullName is "USS Enterprise"cs - 메소드 요구사항 ( Methods in Protocol )
- 프로퍼티와 마찬가지로 프로토콜에 지정된 메소드 요구사항을 말하는 것이다.
- 메소드의 몸체 ( 함수의 body ) 는 없다. 세부 사항이 아니라 그 틀만 지켜달라는 것이기 때문에.
- 타입 메소드는 프로퍼티의 경우와 마찬가지로 static, class 키워드 모두 static 으로 통일한다.
- 타입 메소드 정의하고 싶으면 static 키워드로 하면 된다는 뜻.
123protocol RandomNumberGenerator { //프로토콜func random() -> Double //프로토콜을 채택하는 타입안에 이러한 규격의 함수가 있어야 한다.}cs - Mutating 메소드 요구사항
- 값 타입 ( 구조체 혹은 열거형등 ) 에서 값 변경하기 위해 사용하던 mutating 키워드를 프로토콜에 요구사항으로 쓸 수 있다.
- mutating 이 붙은 요구사항은 값 타입인 구조체나 열거형에 해당하지, 클래스에서는 mutating 키워드를 붙이지 않고 func 규칙을 따르면 된다.
- 프로토콜을 타입으로? ( 뒤에 나오는 프로토콜의 핵심인 Delegation 에서 다뤄집니다. )
- 정의한 프로토콜을 하나의 타입으로 사용할 수 있습니다.
- Int 같은 타입으로 쓸 수 있다는 것이 아니라, 해당 프로토콜을 채택한 모든 타입의 인스턴스를 타입으로 받을 수 있다는 말인데, 이해안되죠? 예제로 설명합니다^^
1234567891011121314151617181920212223242526272829303132333435363738394041protocol RandomNumberGenerator { // 랜덤의 수 생성하는 것들이 채택하는 프로토콜.func random() -> Double}class LinearCongruentialGenerator: RandomNumberGenerator {// RandomNumberGenerator 프로토콜을 채택한 의사 난수를 생성하는 클래스// 이 클래스의 수식적 의미보다 난수를 반환하는 클래스라는 것에 집중하세요. 확률론적 지식이 포함되어 있습니다.var lastRandom = 42.0let m = 139968.0let a = 3877.0let c = 29573.0func random() -> Double { // 이 메소드 호출하면 랜덤한 수( 난수 )를 반환합니다.lastRandom = ((lastRandom * a + c).truncatingRemainder(dividingBy:m))return lastRandom / m}}class Dice { //주사위를 표현하는 Dice 클래스.let sides: Int //주사위의 면.let generator: RandomNumberGenerator// 랜덤 수 생성기 프로토콜을 타입으로 가진다 함은?// RandomNumberGenerator 프로토콜을 채택하는 모든 타입(클래스나 구조체나..)의 인스턴스를 설정하는 것입니다.// '인스턴스가 RandomNumberGenerator 프로토콜을 채택한 것이어야 한다'는 것 외에는 별다른 제약사항은 없습니다.// 이 말은 이 프로토콜을 채택한 (예를들어) 클래스의 인스턴스만 generator 상수에 저장될 수 있다.//말로 이해가 안되면 아래의 변수 d6 을 보면 이해됨^^init(sides: Int, generator: RandomNumberGenerator) { // 초기 설정을 위한 초기화 함수.self.sides = sidesself.generator = generator}func roll() -> Int { //주사위 굴리는 행위를 메소드로 표현한 것, 주사위에서 나온 랜덤한 수.return Int(generator.random() * Double(sides)) + 1 // 이 수식의 의미에 빠지지 않아도 됩니다. 확률론적 지식임.}}var d6 = Dice(sides: 6, generator: LinearCongruentialGenerator())// 초기화 함수의 두번째 매개변수 generator 는 RandomNumberGenerator 프로토콜을 채택한 타입의 인스턴스를 받아야 한다고 했쮸?// LinearCongruentialGenerator() 는 RandomNumberGenerator 프로토콜을 채택한 난수 생성하는 클래스의 인스턴스 이쥬? 앞뒤가 척척 들어맞쥬?for _ in 1...5 {print("Random dice roll is \(d6.roll())") // 돌려보면 1~6까지 랜덤한 수 출력됩니다.}cs - 정리하면 ( 타입으로써 프로토콜을 위 예제에서 어떻게 적용했는지 )
- 타입으로써 RandomNumberGenerator 프로토콜을 사용한 것은 Dice 클래스의 let generator 이죠?
- RandomNumberGenerator 프로토콜을 타입으로 갖는 generator 프로퍼티에 저장할 수 있는 것은
- RandomNumberGenerator 프로토콜을 채택한 타입의 인스턴스 이기 때문에
- RandomNumberGenerator 프로토콜을 채택한 클래스인 LinearCongruentialGenerator 클래스의 인스턴스가 들어갈 수 있겠죠?
- 이게 전부입니다. 조금 헷갈릴까봐 최대한 자세하게 주어 생략 않고 썻습니다. 복잡하지만, 정확히 이해하는데 도움 될거에요 !
'스위프트: Swift > 스위프트: 언어자체: 문법' 카테고리의 다른 글
Swift4 : 제네릭 : #Generics : #왜필요해? : #where키워드 : #제약사항걸기 (0) 2018.09.08 Swift4 : 프로토콜 2 : #델리게이트 패턴 : #델리게이션 (2 / 2) (0) 2018.09.07 Swift4 :메소드 : Method : #메소드의 범위 : #mutating : #self #값 타입 수정 (0) 2018.09.06 Swift4 : 프로퍼티 : #Properties : #get, set " #willSet,didSet (0) 2018.09.05 Swift4 : 클래스와 구조체 : #값을 대하는 방식 : #값 타입, 참조 타입 : #value type : #reference type : #=== 연산자 (0) 2018.09.05 댓글