프로토콜 / 확장 / is

냐옹·2024년 7월 15일
0

IOS

목록 보기
31/32
  • 프로토콜 안의 프로퍼티 / 메서드는 모두 require이다. 따라서 기본값으로 세팅을 하거나 채택하는 곳에서 구현하지 않으면 에러가 난다.

  • 만약에 옵셔널로 형을 지정해놓고, 값을 할당해주지 않는다 하더라도 그것도 기본값으로 세팅을 한거다. 옵셔널자료형은 초기화가 되지 않을 시에 nil로 자동 초기화된다.

  • 클래스의 경우에 초기화를 하지 않더라도, 기본초기화자가 있기 때문에 괜찮다. ( 아주 괜찮다는건 아니고 )

  • 프로토콜은 타입이다.

만약에 프로토콜 멤버를 required로 하기 싫다면
  • @objc optional 을 붙인다.
  • 프로퍼티 앞에도 @objc optional을 붙이고, 프로토콜 앞에도 @objc를 붙여 선언한다.
@objc protocol Band : AnyObject{
	var drum : String { get set }
  	var vocal : String { get set }
  	var piano : String { get set }
  	@objc optional var bass : String { get set }
  
  	func play()
}
  • 프로토콜에 선언되는 프로퍼티는 항상 var로 선언되어야 한다.

  • 구조체의 경우, mutating이 필요하면 프로토콜 자체에 추가
    ㄴ 메서드 안에서 프로퍼티 값을 변경해야할 경우 반드시 mutating키워드를 func 앞에 붙여줘야 한다.

protocol Renameable{
	mutating func changeName(newName : String)
}

struct Sodeul : Renameable{
	var name : String = "Johnson"
  
  	mutating func changeName(newName : String){
    	self.name = newName
    }
}

class DeulSo : Renameable{
	var name : String = "sodeul"
  
  	func changeName(newName : String){
    	self.name = newName
    }
}
  • 프로토콜은 자체적으로 인스턴스를 생성할 수가 없다. 때문에 해당 프로토콜을 준수하는 구조체 / 클래스 / 열거형 인스턴스를 프로토콜 타입으로 캐스팅해서 전달하는 방법을 주로 사용한다.
is 해당 인스턴스는 이 프로토콜을 채택하고 있는가
protocol Band{}
protocol Solo{}

struct Beatles : Band{}

let beatles = Beatles.init()
beatles is Band // true
beatles is Solo // false
Protocol과 Extension
  • 여러개의 클래스가 프로토콜을 채택할 수 있다.

  • 해당 클래스들에서 공통적으로 play()라는 메서드를 구현하고 있다고 쳐보자. 근데, 기본적으로 비슷한 동작을 하고 5개가 한다고 하면 이 중에 1개만이 다른 동작을 하고 있다고 쳐보자.

  • 참고로 프로토콜에 선언된 메서드는 기본값을 가질 수 없다.

  • 그렇다면 protocol에서

protocol ExampleProtocol{
	func play() -> Void
}

가 있다고 했을 때 확장을 해서 이 프로토콜의 메서드 기본동작을 지정해 줄 수 있다.

protocol ExampleProtocol{
	func play() -> Void
}

extension ExampleProtocol{
	func play() -> Void{
    	print("play")
    }
}
  • 이후에는 구현하지 않고 바로 사용하면 사전에 확장에 포함된 메서드가 실행되게 된다.

  • 원치 않을 경우에는 구현하면 된다.

  • where를 통해서 기본 메서드를 제공하는 것에 제한을 둘 수도 있다.

protocol Human{}
protocol Band{
	func play()
}

extension Band where Self : Human{
	func play() {
    	print("play!")
    }
}

0개의 댓글