프로그래밍 놀이터/iOS

[Objective-C] 프로토콜

돼지왕 왕돼지 2018. 1. 4. 08:30
반응형

 [Objective-C] 프로토콜


출처 : OS X 구조를 이해하면서 배우는 Objective-C Chap 12.


Notice : 정리자(돼지왕 왕돼지)가 remind 하고 싶은 내용이나 모르는 내용 기반으로 정리하는 것이기 때문에 구체적인 내용은 책을 사서 보시기를 권장드립니다.


12.1. 프로토콜 개념


* 12.1.1. 프로토콜이란



* 12.1.2. 객체 프로토콜


-

어떤 프로토콜을 채용해서 그 메서드를 모두 구현한 클래스는 해당 프로토콜에 적합(conform)하다(또는 준거한다)라고 한다.

어떤 프로토콜에 적합한 클래스를 상속한 서브 클래스도 그 프로토콜에 적합하다.

또한 클래스가 어떤 프로토콜에 적합할 때는 그 인스턴스에 대해서도 해당 프로토콜에 적합하다고 표현할 수 있다.




12.2. Objective-C 프로토콜 선언


* 12.2.1. 프로토콜 선언


-

프로토콜 이름은 기존 클래스명과 겹쳐도 괜찮다.




* 12.2.2. 프로토콜 채용


-

프로토콜을 지정해서 클래스 인터페이스를 선언하고 있을 때 클래스가 그 프로토콜을 채용(adopt)하고 있다고 한다.



-

여러 프로토콜을 동시에 채용할 때, 프로토콜에 같은 메서드 선언이 중복해서 포함되더라도 문제가 없다.

프로토콜 S 와 T가 있고, 둘을 동시에 채용할 때, 양쪽에 모두 copy: 메서드가 있다고 해보자.

구현 부분에서 copy: 를 구현하면 이 메서드는 프로토콜 S 의 구현이자 프로토콜 T 구현도 되는 것이다.


하지만 셀렉터가 같더라도 인수나 반환값의 형이 다른, 즉 서명이 다른 메서드가 프로토콜 사이에 중복되어 있을 때는 문제가 생긴다.

하나의 클래스 내부에는 같은 셀렉터를 가진 다른 메서드를 선언할 수 없기 때문이다. ( overload 불가능 )

이런 프로토콜을 여러 개 포함하는 클래스는 정의할 수 없다.




* 12.2.3. 프로토콜 상속


-

어떤 프로토콜에 다른 메서드군을 추가해서 새로운 프로토콜을 선언할 수 있다.



-

이렇게 선언한 프로토콜은 상속한 프로토콜이 가진 메서드군과 새롭게 추가한 메서드군 모두를 다 가진다.

또한 상속할 프로토콜은 여러 개도 가능하다.




* 12.2.4. 프로토콜 지정 형식 선언


-

-(void) aFunctionWithView:(NSView<Clickable> *)view;


위와 같은 함수가 있다면, 인수가 단순한 NSView 형의 인스턴스가 아니라 카테고리 또는 상속을 사용한 프로토콜 Clickable 에 적합한 객체이어야만 하다는 것을 정적으로 보여준다.



-

코드로는 프로토콜이나 추상 클래스에 따른다는 것밖에 알 수 없는 구체적인 클래스명이 나와 있지 않은 객체를 익명 객체(anonymous object)라고 부른다.




* 12.2.5. 프로토콜 전방 선언


-

프로토콜명을 헤더 파일 속에 형식 선언으로만 사용할 거라면 전방 참조 지정이 가능하다.

이는 다음과 같이 작성한다.


@protocol Clickable;



* 12.2.6. 프로토콜 적합성 확인


-

컴파일러 지시자 @protocol() 을 사용하면 지정한 프로토콜을 표현하는 데이터를 가리키는 포인터를 얻을 수 있다.

@protocol() 이 표현하는 식의 값을 (Protocol*) 이라는 형을 가진 변수에 대입할 수도 있다.



-

객체가 어떤 프로토콜에 적합한지 어떤지 조사하려면 NSObject 에 정의된 다음 메서드를 사용할 수 있다.

이 녀석은 class method, instance method 둘 다에 존재한다.


(BOOL) conformsToProtocol: (Protocol*) aProtocol

     리시버 클래스가 aProtocol 로 지정한 프로토콜에 적합하다면 YES 를 돌려준다.




* 12.2.7. 필수 기능과 옵션 기능 지정


-

프로토콜 선언 속에서 컴파일러 지시자 @optional 또는 @required 를 사용하면 그 이후에 선언한 메서드는 옵션 또는 필수 메서드가 된다.

@optional 과 @required 는 순서에 상관없이 여러 번 나와도 괜찮다.

이런 지정이 없는 메서드는 @required 가 지정된 것처럼 반드시 구현해야 한다.




* 12.2.8. 프로토콜을 사용한 프로그램 예제




12.3. 비형식 프로토콜

* 12.3.1. 비형식 프로토콜이란


-

메서드군을 선언하기 위해 NSObject 카테고리로 선언하는 방법이 있다.

이것을 비형식 프로토콜(informal protocol) 또는 간이 프로토콜이라고 부른다.

비형식 프로토콜과 구별하기 위해 앞서 설명한 프로토콜을 형식 프로토콜(formal protocol) 또는 정식 프로토콜이라고 부른다.



-

비형식 프로토콜은 카테고리 선언만으로 구현이 되지 않는다.

실제로 카테고리로 선언한 메서드에는 구현이 따르지 않더라도 컴파일되고 실행되어 버린다.

하지만 메시지 송신은 실행 에러를 일으킨다.



-

비형식 프로토콜로 선언된 메서드군을 이용하고자 하는 클래스는 그 메서드를 인터페이스에서 다시 선언하고(필수는 아니다.)

구현 부분에 정의를 작성한다.

하지만 그 카테고리의 모든 메서드를 구현해야 하는 건 아니다.



-

비형식 프로토콜은 루트 클래스 카테고리일 뿐이므로 형식 프로토콜을 사용할 때처럼 컴파일할 때 형식을 확인하거나 실행할 때 프로토콜에 적합한지 확인할 수 없다.

비형식 프로토콜에 따라 메서드가 구현되었는지 조사하려면 각각의 메서드에 대해 respondsToSelector: 를 사용해 볼 수밖에 없다.



-

정리하면..

     비형식 프로토콜은 NSObject 클래스 카테고리로 선언된다.

     비형식 프로토콜로 선언된 메서드 구현은 필수가 아니다.

     컴파일할 때 비형식 프로토콜의 적합 여부를 확인하는 방법이 없다.

     실행할 때 비형식 프로토콜의 적합 여부를 확인하는 방법이 없다. 각각의 메서드를 구현했는지 확인해야 한다.




* 12.3.2. 비형식 프로토콜의 용도


-

Cocoa 환경에서 비형식 프로토콜을 사용하는 상당수의 경우가 시스템(프레임워크) 쪽에서 사용자 프로그램 쪽의 객체를 호출해서 정보를 주고받는 경우이다.



-

비형식 프로토콜은 카테고리 메서드를 실제로 정의할 때와 달리 NSObject 에 실질적으로 무언가를 더하는 건 아니다.

카테고리 선언을 임포트한 소스 파일 안에서 메서드 프로토타입 선언으로 작용한다.



-

전에는 메서드군에 있는 모든 것이 필요한 게 아니라면 보통 비형식 프로토콜로 선언했었다.

Objective-C 2.0 에서는 옵션 딸린 프로토콜을 사용할 수 있게 되어 다양한 부분에서 프로토콜을 사용한 프로그래밍 스타일이 도입되었다.





반응형