개발 관련/iOS SWIFT

[Swift] Protocol 프로토콜이란?

magpiebros 2023. 4. 5. 17:36
반응형

안녕하세요 맥파이입니다.

오늘은 대망의 protocol입니다.

프로토콜이라는건 많이 들어도 보고, 어렵기도 하고 피하고만 싶어질수 있습니다.

 

어느 누군가가 만들어 놓은 프로토콜 코드를 보면 몸서리쳐 질수도 있기 때문입니다.
상속도 아닌것이 괜히 복잡하게만 보일수 있기 때문이죠.

 

이제 시작해봅시다.

 

 

protocol

프로토콜은 요구사항을 정의하고, 구조체, 클래스, 열거형은 프로토콜을 채택해서 요구사항을 실제로 구현하는 방식으로 사용됩니다.
프로토콜은 정의를 할뿐 기능 구현은 하지 않습니다.

 

프로토콜은 다음과 같은 모습으로 생겼습니다.

 

protocol ‘이름’ {
//프로토콜 정의
}

 

프로토콜의 용법

  • Property Requirements
  • Method Requirements
  • Initializer Requirements
  • Delegation

프로토콜의 위와 같은 4가지 용법이 있는것으로 보입니다.
용법이라고 하는게 맞는건진 모르겠으나.... 
일단 설명 해보죠...

 

Property Requirements

프로퍼티 선언시 이름과 타입, getter/setter만 명시한다.
항상 var로 선언해야 한다.


protocol SampleProtocol {
    var sample: Int { get  set }
    var dummy: String { get }   
}

get, set을 선언함으로서 기능의 제한을 둘 수 있습니다.

 

 

Method Requirements

인스턴스 메소드와 타입 메소드를 정의할수도 있다.
mutating 키워드를 사용해 인스턴스에서 변경이 가능하다고 표현할수 있다. (값타입에서 사용 가능)

인스턴스 메소드와 타입 메소드를 정의할수도 있다.

protocol SampleProtocol {
//기본값을 설정할수 없다.
    func a(a: Int = 0)    //에러 발생
}

 

mutating 키워드를 사용할수 있습니다.

mutating을 사용하여 값 타입을 변경할 수 있습니다. 

protocol SampleProtocol {
//기본값을 설정할수 없다.
    mutating func a(value: Int)
}

sturct A: SampleProtocol {
var price: Int = 0
    mutating func a(value: Int) {
    price += value
    }
}




Initializer Requirements

이니셜라이저 정의가 가능합니다.

protocol InitProtocol {
init(price: Int)
}

class SampleClass: InitProtocol {
required init(price: Int) {
}
}


required에 대해서도 나중에 글을 작성해 볼께요.
일단은 무시하고 넘어가시죠.
protocol에서 정의시에 붙는 경우가 있긴합니다.


일반적인 이니셜라이즈 정의시 아래와 같이 사용도 가능합니다.

override에 대해서도 글을 작성해볼 예정입니다.

protocol InitProtocol {
init()
}

class MomClass: InitProtocol {
init() {
}
}

class BabyClass: MomClass, InitProtocol {
// required override를 붙여줘야 한다.
required override init() {
}
}

 

Delegation

인스턴스에 특정 행위에 대리역할을 지시하는 패턴이다.
UITableViewDelegate 같은 것들 많이 보셨죠?
- Delegation 프로토콜을 정의하는 것으로 구현할 수 있습니다.



프로토콜 타입의 제한

protocol ClassTypeProtocol: AnyObject { }

프로토콜에 AnyObject를 추가하면 클래스에서만 해당 프로토콜을 채택할 수 있게 됩니다.
Object로 제한을 걸어버렸기 때문이죠.

 

추가 학습 - 보너스

 

프로토콜의 상속

구조체, 클래스, 열거형뒤에 콜론(:)을 붙이고 채택할 프로토콜 이름을 명시해준다.
슈퍼클래스를 상속받는경우, 슈퍼클래스를 가장 앞에 명시해준다.

class Baby: Mom, ProtocolA { }


프로토콜을 채택하는 타입은 해당 프로퍼티를 구현해줘야 합니다.

당연한 이야기겠지요? 

class TestClass: SampleProtocol {
    var sample: Int  = 10
    var dummy: String  = “hello”

}

Protocol Composition
protocol Input { }
protocol Output { }
protocol VM: Input, Output { }

class MyRxClass: VM { }



프로토콜의 타입 확인 방법

is, as? as!를 사용하여 타입 확인이 가능한데요, 이것도 나중에 한번 정리를 해보겠습니다.


프로토콜을 어떻게 쓸것인가?

정답은 없는것 같습니다.

누군가가 만들면 멋진 코드같고, 미워하는 사람이 만들면 개떡같은 코드로 보일수 있죠.

 

프로토콜의 함수가 1개라면 함수로 만들어 쓰자구요.
함수가 2개 이상이라면 프로토콜을 써볼수 있을것 같습니다.

 

정답은 없는 부분이라, 고민해보고 써야 할 것 같습니다.

 

오늘은 여기까지 또 만나요!!

 

반응형