Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
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
Archives
Today
Total
관리 메뉴

주니곰의 괴발노트

Swift - Protocol(정의, 프로퍼티) (1/4) 본문

iOS

Swift - Protocol(정의, 프로퍼티) (1/4)

Jhe2 2023. 2. 3. 21:47

정의

  • 스위프트에서 프로토콜을 통해 메서드, 프로퍼티, 특정 작업 또는 기능들의 대한 요구사항을 사전에 정의를 해두고 클래스, 구조체, 또는 열거형에 의해 채택하여 활용
  • 채택하여 활용하는 곳에서는 프로토콜에서 요구사항을 지정하는 것 외에도 요구사항의 일부를 구현하거나 준수하는 타입에 추가 기능을 구현하기 위해 프로토콜을 확장가능
  • 다음과 같이 사용
protocol SomeProtocol {
    // protocol definition goes here
}

 

  • 사용자 정의 타입은 콜론 뒤에 작성하여 특정 프로토콜을 채택하며 여러 프로토콜을 채택가능
struct SomeStructure: FirstProtocol, AnotherProtocol {
    // structure definition goes here
}

 

  • 클래스의 상속의 경우, 클래스 먼저 작성하고 그 뒤에 프로토콜을 작성
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
    // class definition goes here
}

 

프로퍼티 요구사항

  • 프로토콜에서는 특정 이름과 타입을 가진 인스턴스 프로퍼티 또는 타입 프로퍼티를 제공하기 위해 모든 준수하는 타입을 요구할 수 있음
  • 요구된 프로퍼티 이름과 타입만 지정하고 프로퍼티가 저장 프로퍼티 또는 계산 프로퍼티인지에 대한 것은 지정하지 않음
  • 각 프로퍼티가 gettable인지 gettable과 settable인지도 지정해줘야 함
  • 프로토콜에서 gettable과 settable인 프로퍼티를 정의했을 경우, 저장 프로퍼티 또는 읽기전용 계산 프로퍼티는 해당 요구사항을 충족할 수 없음
  • 프로토콜에서 gettable인 프로퍼티를 정의했을 경우, 모든 종류의 프로퍼티를 사용가능하며 settable 또한 해당 요구사항 충족 가능
  • 따라서 gettable로 초기설정해 놓을 경우, gettable과 settable 프로퍼티 모두 사용 가능
  • 프로퍼티 요구사항은 항상 var 키워드와 함께 변수 프로퍼티로 선언
  • gettable과 settable 프로퍼티는 타입 선언 뒤에 { get set } 으로 작성하여 나타내고 gettable 프로퍼티는 { get } 으로 작성

 

protocol SomeProtocol {
    var mustBeSettable: Int { get set }
    var doesNotNeedToBeSettable: Int { get }
}

 

  • 항상 프로토콜에서 정의할 때 static 키워드를 타입 프로퍼티 요구사항에 접두사로 사용
  • 클래스에 의해 구현될 때 class 또는 static 키워드를 붙일 수 있는 경우와 비슷
protocol AnotherProtocol {
    static var someTypeProperty: Int { get set }
}

 

  • FullyNamed 프로토콜은 다른 준수하는 타입을 지정하지 않으며 타입이 자체에 대한 전체 이름을 제공해야 된다고만 지정
  • FullyNamed 프로토콜을 채택한 모든 클래스 및 구조체, 열거형은 String 타입의 fullName 이라는 gettable 인스턴스 프로퍼티를 가져야 함
  • 다음은 FullyNamed 프로토콜은 채택하고 준수하는 구조체에 대한 예
  • Person의 콜론 뒤에 FullyNamed 프로토콜을 채택하고 Person의 각 인스턴스는 String 타입의 fullName 이라는 단일 저장된 프로퍼티를 가짐
  • 이것을 FullyNamed 프로토콜의 단일 요구사항과 일치하고 Person은 프로토콜을 올바르게 준수하고 있다고 얘기함 (Swift는 프로토콜 요구사항이 충족되지 않으면 컴파일 시 에러가 발생) 
protocol FullyNamed {
    var fullName: String { get }
}

struct Person: FullyNamed {
    var fullName: String
}

let john = Person(fullName: "John Appleseed")
// john.fullName is "John Appleseed"

 

  • 다음은 스타십에 대해 읽기전용 계산 프로퍼티로 fullName 프로퍼티 요구사항을 구현
  • 각 Starship 클래스 인스턴스는 필수로 name 과 옵셔널 prefix 를 저장
  • fullName 프로퍼티는 prefix 값이 존재하면 사용하고 스타십에 대한 전체 이름을 생성하기 위해 name 의 앞에 추가
class Starship: FullyNamed {
    var prefix: String?
    var name: String
    
    init(name: String, prefix: String? = nil) {
        self.name = name
        self.prefix = prefix
    }
    
    var fullName: String {
        return (prefix != nil ? prefix! + " " : "") + name
    }
}

var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
// ncc1701.fullName is "USS Enterprise"

 

자료 출처

https://docs.swift.org/swift-book/LanguageGuide/Protocols.html

Comments