IOS- 17

김정현·2023년 3월 24일
0

IOS 개발공부 일지

목록 보기
17/27

프로토콜

프로토콜이란 특정 역할을 하기 위한 메서드, 프로퍼티, 기타 요구사항 등의 청사진을 말한다.
어떤 프로토콜의 요구사항을 모두 따르는 타입을 '해당 프로토콜을 준수한다'고 표현한다. 프로토콜은 정의하고 제시할 뿐 구현을 하지는 않는다.

protocol 프로토콜 이름 {
	프로토콜 정의
}

구조체, 클래스, 열거형 등에서 프로토콜을 채택하려면 타입 이름 뒤에 :을 붙여준 뒤 프로토콜 이름을 쉼표로 구분하여 명시해준다.

Struct SomeStruct: Aprotocol, Bprotocol {
   구조체 정의
}

클래스가 다른 클래스를 상속받는다면 상속받을 클래스 이름 다음에 채택할 프로토콜을 나열해준다.

프로토콜 요구사항

프로퍼티 요구

프로토콜은 자신을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구할 수 있다. 그러나 프로토콜은 그 프로퍼티의 종류(연산, 저장)는 신경쓰지 않는다. 이름과 타입만 맞도록 구현해주면 된다.
단, 읽고 전용일지 읽고 쓰기 가능일지는 프로토콜이 정해줌.

  • 프로토콜의 요구사항은 항상 var 키워드를 사용한 변수 프로퍼티로 정의한다.
  • 읽고 쓰기가 모두 가능한 프로퍼티는 프로퍼티 정의 뒤에 { get set }이라 명시한다.
  • 읽기 전용 프로퍼티는 정의 뒤에 { get } 이라고 명시해준다. (프로퍼티를 읽고 쓰기로 정의해도 괜찮음)
  • 타입 프로퍼티를 요구하기 위해서는 var앞에 static 키워드를 사용한다.
protocol somprotocol {
	var settableproperty: String { get set }           //var 키워드로 프로토콜 요구사항(읽고 쓰기) 정의 
    var notneedtobe: String { get }
}

protocol Anotherprotocol {
	static var sometypeproperty: Int { get set }         //타입 프로퍼티를 요구하려면 static 키워드 사용 
}

메서드 요구

특정 인스턴스 메서드나 타입 메서드를 요구할 수도 있다. 요구할 메서드는 프로토콜 정의에서 작성한다. 메서드의 실제 구현부인 {} 부분은 제외하고 이름, 매개변수, 반환 타입 등만 작성하며 가변 매개변수도 허용한다.

  • 메서드 요구에서는 매개변수 기본값을 지정할 수 없다.
  • 타입 메서드를 요구할 때는 마찬가지로 static 키워드를 명시한다.
protocol A {
	func B(data: Any)
}

가변 메서드 요구

메서드가 인스턴스 내부의 값을 변경할 필요가 있을 때가 있다. 인스턴스 메서드에서 자신 내부의 값을 변경하고자 할 때 메서드의 func 키워드 앞에 mutating 키워드를 적어 인스턴스 내부의 값을 변경한다고 명시한다.

참조타입인 클래스의 메서드 앞에는 mutating을 명시하지 않아도 인스턴스 내부 값을 바꾸는데 문제가 없지만, 값 타입인 구조체와 열거형의 메서드 앞에서는 mutating 키워드를 붙여야한다.

이니셜라이저 요구

이니셜라이저를 정의하지만 구현은 하지 않는다. 매개변수를 지정할 뿐, {}안을 구현하지는 않는다.

protocol Named {
	var name: String { get }
    
    init(name: String)
}

클래스의 경우에는 요구에 부합하는 이니셜라이저를 구현할 때는 required 식별자를 붙인 요구 이니셜라이저로 구현해야한다. 이 부모클래스를 상속 받은 모든 자식클래스는 해당 프로토콜을 모두 준수해야한다. 그렇기에 반드시 요구 이니셜라이저로 구현해야한다.

class Person: Named {        //Named프로토콜 준수
	var name: String
    
    required init(name: String) {   //요구 이니셜라이저로 구현
    	self.name = name 
    }
}

이 클래스를 상속받는 자식클래스는 override, required 모두 표기해야한다. (순서는 무관)

  • 클래스 전용 프로토콜을 만들기 위해서는 프로토콜 상속리스트 맨 처음에 class 키워드가 위치하면 된다.

프로토콜 상속

프로토콜은 다중 상속이 가능하다. : 뒤에 상속 받을 프로토콜을 , 로 나열하면 된다.

프로토콜 준수 확인

프로토콜도 타입이기 때문에 타입캐스팅으로 준수하는지 확인, 다운캐스팅 시도, 강제 다운캐스팅을 할 수 있다.

print(KIM is Named)    //true  (Named는 프로토콜)

if let casted instance: Named = KIM as? Named {         //(is랑 다른점을 명확히 모르겠음)
	}

0개의 댓글