iOS/문법

Swift 문법과 친해지기 - protocol

HJ39 2023. 1. 4. 20:16

프로토콜

  • 구조체, 클래스, 열거형은 프로토콜을 채택해서 특정 기능을 실행하기 위한 프로토콜의 요구사항을 실제로 구현할 수 있다.
  • 스스로 기능을 구현하지 않는다.
  • 하나의 타입으로 사용되기 때문에 다음과 같은 타입에서 사용가능 하다.
    • 함수, 메소드, 이니셜라이저의 파라미터 타입, 상수, 변수, 프로퍼티 타입, 배열, 딕셔너리 원소 타입

 

간단히 말해 프로토콜은 해당 기능에 필요한 요구사항을 선언해두는 것이다.

다른 언어들의 인터페이스와 비슷한 개념 같다.

 

□ 프로토콜 예시

protocol Band{
    var drum: String {get set}
    var vocal: String {get set}
    var piano: String {get set}
    var guitar: String {get set}
    
    func play()
}

struct Aband : Band{
    var drum: String
    var vocal: String
    var piano: String
    var guitar: String
    
    func play() {
        print("play")
    }
}

 

만약 프로토콜을 사용하는데 optional을 사용해야 하는 경우 

다음과 같이 수정하여 사용할 수 있다.

 

□ optional 사용하는 프로토콜

@objc protocol Band: AnyObject{
    var drum: String {get set}
    var vocal: String {get set}
    var piano: String {get set}
    var guitar: String {get set}
    @objc optional var bass: String {get set}
    
    func play()
}

class Aband : Band{
    var drum: String = "A"
    var vocal: String = "B"
    var piano: String = "C"
    var guitar: String = "D"
    
    func play() {
        print("play")
    }
}

→ @objc를 사용하여 optional을 사용하기 때문에 objective-C에서 사용이 된다는 의미이다.

그런데 objective-C에서 프로토콜은 struct 구조체를 채택할 수 없게 되어 있다. 따라서 클래스 방식으로만 사용할 수 있다.

protocol 앞에 @objc가 붙는 순간 프로토콜은 AnyObject로 자동으로 채택된다.

optional로 지정한 bass이므로 클래스에서 필요 없다면 사용하지 않아도 된다.

 

getter, setter

프로토콜은 getter, setter에 따라서 let, var의 사용 여부가 나뉜다.

get만 사용하는 경우 let, var 두 개 다 사용 가능하지만 set인 경우 var만 사용해야 한다.

 

mutating

protocol Renameable {
    mutating func changeName(newName: String)
}
 
struct Sodeul: Renameable {
    var name: String = "sodeul"
    
    mutating func changeName(newName: String) {
        self.name = newName
    }
}
 
class DeulSo: Renameable {
    var name: String = "sodeul"
    
    func changeName(newName: String) {
        self.name = newName
    }
}

프로토콜에 mutating을 사용하는 경우 구조체에서는 선언할 때 mutating을 앞에 작성해야 하고 class의 경우에는 작성하지 않아도 된다.

 

제네릭 함수

프로토콜 내부에 제네릭 함수를 선언할 수 있다.

제네릭 관련해서는 다시 공부해야 할 것 같다..ㅠ

 


프로토콜 vs 인터페이스

  프로토콜 인터페이스
기본 값 설정 불가능 가능
요구사항 구현 정도 optional로 선택적으로 구현 가능 모두 구현해야함
정적 변수 선언 사용 가능 사용 불가능

 

 

 

 

#참고한 사이트 

  1. https://babbab2.tistory.com/180
  2. https://babbab2.tistory.com/178
  3. https://babbab2.tistory.com/176
  4. https://babbab2.tistory.com/175
  5. https://babbab2.tistory.com/174
  6. https://velog.io/@youngking0914/iOSSwift-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-vs-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%B0%A8%EC%9D%B4%EC%A0%90