[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 에서는 옵션 딸린 프로토콜을 사용할 수 있게 되어 다양한 부분에서 프로토콜을 사용한 프로그래밍 스타일이 도입되었다.
다음 글 : [Objective-C] 객체 복사와 저장
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[Objective-C] 블록 객체 (0) | 2018.01.06 |
---|---|
[Objective-C] 객체 복사와 저장 (0) | 2018.01.05 |
[Objective-C] 추상 클래스와 클래스 클러스터 (0) | 2018.01.03 |
[Objective-C] 카테고리 (0) | 2018.01.02 |
[Objective-C] Foundation 프레임워크의 중요 클래스 - NSDictionary, NSValue, NSNumber, NSURL (0) | 2018.01.01 |
댓글