티스토리 뷰


Protocol

‘A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements’

다음에서 발췌: Apple Inc. ‘The Swift Programming Language (Swift 4.0.3).’ iBooks. https://itunes.apple.com/kr/book/the-swift-programming-language-swift-4-0-3/id881256329?mt=11

  • Method

  • Property(프로퍼티에서의 사용? 다만, 프로토콜은 의존성을 줄이기 위한 것이니 되도록이면 사용하지 않는 편이 좋다.)

  • 특정한 클래스가 동작할때 필요한것을 명시해주는 것


왜 사용하는건데?

    제가 받은 느낌은...

    • 객체간의 의존성을 줄이기위해 사용합니다.

    • 두 개 이상의 객체가 서로 메세지를 주고받는데(이야기를 주고받는다고 할때), 직접적으로 Property를 변경하는 것이 아닌 프로토콜이라는 규약을 통해서만 메세지를 주고 받아라 입니다.<br> 큰 사다리게임이 작은 사다리게임이 되어가는 예제!

  • 그렇다면 기존의 객체 지향에서 인터페이스와 Swift의 Protocol은 뭐가 다른가?

    • 다른 언어의 인터페이스가 기억이 나질 않지만 우선 swift의 Protocol은 Type으로 쓸 수 있다는게 가장 큰 차이!

    • 여러 객체의 타입을 처리하는 메소드의 경우 보통 타입을 Any를 사용합니다. 만약 Protocol Type으로 사용하게 된다면, Any타입의 객체들에 필요한 정보를 각각의 객체들에게 위임하여 (Delegation ?)처리를 하게 만들어 줄 수 있고, Any타입이 아니라 Protocol 을 채택한 객체들만으로 타입을 명시 해줄 수 있다는 장점이 있습니다.

protocol CardGameMoveAble: PushAble, PopAble {
   func pickCard(xIndex: Int, yIndex: Int) -> Card
   func lastCard(xIndex: Int) -> Card?
}

protocol PushAble {
   func pushCard(card: Card, index: Int)
}

protocol PopAble {
   func popCard(xPoint: Int)
}

class FoundationDeck: CardGameMoveAble {
   private var foundationDeck = Array.init(repeating: Deck(cards: [Card]()), count: 4)
   
   func pickCard(xIndex: Int, yIndex: Int) -> Card {
       return foundationDeck[xIndex].cards[yIndex]
   }
// 중략~~

@objc private func playGameCardStack(notification: Notification) {
   // 중략
   guard let originDeck = checkCardGameModel(originView) else { return }
   let pickedCard = originDeck.pickCard(xIndex: Int(point.x), yIndex: Int(point.y))
   // 중략~
}

private func checkCardGameModel(_ originView: UIView) -> CardGameMoveAble? {
       switch originView.tag {
       case SubViewTag.foundationView.rawValue:
           return foundationDeck
       case SubViewTag.gameCardStackView.rawValue:
           return gameCardStack
       case SubViewTag.openDeckView.rawValue:
           return openDeck
       default:
           return nil
       }
   }
  • 자세한 설명은 JK...


프로토콜 너이녀석

  • 보통 프로토콜을 사용하는 객체에 "채택(Conform)"한다 라는 용어 사용.

  • Class, Struct, Enum 까지 채택가능.

  • 문법적으로 어떻게 사용하는가?


protocol SomeProtocol {
   // protocol definition goes here
}

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.37464991998171"
print("And another one: \(generator.random())")
// Prints "And another one: 0.729023776863283

Enum에서 사용


protocol Togglable {
   mutating func toggle()
}

enum OnOffSwitch: Togglable {
   case off, on
   mutating func toggle() {
       switch self {
       case .off:
           self = .on
       case .on:
           self = .off
       }
   }
}
var lightSwitch = OnOffSwitch.off
lightSwitch.toggle()
// lightSwitch is now equal to .on

기타... Initializer Requirements

훨씬 좋은 예제는 여기에있다!목차에서 Protocol을 보시면 됩니다. 예제는!

'CS > Swift' 카테고리의 다른 글

[Swift]백의 자리마다 콤마찍기  (0) 2017.12.29
[Swift]Value vs. Reference  (0) 2017.11.07
[Swift]객체와 테스트  (0) 2017.11.07
[Swift]오늘의 이슈 - 예외처리관련  (0) 2017.11.05
[Swift]String 문자열 하나씩 쪼개기  (1) 2017.11.03
Comments