Protocol의 종류 : Formal Protocol

- formal protocol은 다음과 같이 @protocol이라는 directive를 이용해서 선언한다.

@protocol ReferenceCounting
- (int)refCount;
- incrementCount;
- decrementCount;
@end

- protocol 이름은 global하게 access할 수가 없다. protocol은 클래스랑 연관을 시켜서 써주는 것이지 단독적으로 쓰는것이 아니기 때문이다. 즉 어떤 protocol을 쓰려면 class가 그 프로토콜을 “준수”해야 하는 것이다. 즉 그 프로토콜을 adopt 혹은 채용해야 한다.

@interface ClassName : ItsSuperclass < protocol list >
@interface ClassName ( CategoryName ) < protocol list > // 카테고리가 protocol을 받으려면
@interface ClassName ( CategoryName ) < protocol_1, protocol_2 >

- 단 protocol을 받아들일 클래스나 카테고리 파일에서는, 반드시 그 프로토콜이 선언된 헤더파일을 import해야만 한다. 그리고 그렇게 받아들여진 프로토콜안에 정의된 method들은 클래스나 카테고리 인터페이스의 다른 부분에서 또 선언되면 안된다.
  -> 당연한 듯..

- 물론 프로토콜 method외엔 아무 method도 가지지 않는 클래스도 있을 수 있다.

@interface Formatter : NSObject < Formatting, Prettifying >
@end

- 한 클래스나 카테고리가 일단 어떤 프로토콜을 준수하겠다고 한다면,그 클래스나 카테고리는 준수하고자 하는 프로토콜에 선언된 모든 method를 다 구현해야 한다. 그렇지 않으면 컴파일러가 경고를 하게 된다.

- formal protocol은 선언시에 @protocol이란 특별한 directive를 써 놓았을 뿐, 그 구현은 역시 informal protocol과 마찬가지로 class내에서 한다.
Category는 어떤가? 그 선언과 구현이 별도로 되어 있다. 즉 클래스에 종속되어 있지 않다.
그렇다면 Category와 Protocol의 궁극적인 차이는 무엇일까?
Objective-C의 장점이 알지 못하는 객체에다가 메시지를 보내고, 그 헤더파일이 없는 클래스를 상속이 아닌 수평적인 수준에서 새 함수를 더 넣을 수 있다는 것이다. Category는 이미 있는 클래스를 수평적으로 확장을 할 때, 유용하다. 단 그때, 그 클래스의 소스코드가 없을 수 있다. 그러므로 별도의 장소에서 다음과 같이 한다.

@implementation ClassName ( CategoryName )
method definitions
@end

하지만 protocol인 경우엔 저 “ClassName” class 자체에서 하게 된다. 즉 protocol인 경우엔, 내가 지금 만드는 클래스가 어떤 것을 다 가져야 할지 이미 알고 있는 경우란 소리다.
Category와 Protocol 개념은 클래스들을 그 행위로서 구분지어줄 수 있는 것들이지만, 이렇듯 미리 무엇을 할지 알고 있느냐 없느냐에 따라 용례가 갈린다고 볼 수 있다. 또한 Category의 경우에는 뭔가 해당 클래스의 versioning이라는 점이다. 결국 보면 protocol과 비슷해질 수는 있겠지만, 개념적으론 좀 차이가 있다.
 -> Category는 (소스코드가 없는) 클래스를 수평적으로 확장(Versioning 개념).
     Protocol은 소스를 알고 있는 여러 클래스들에게 동일한 처리 규약(처리내용은 다르겠지만 인터페이스는 같다)을 주는 것. 정도 일려나?
     사용례를 봐야 좀 확실하게 개념이 잡힐 듯. Category는 그렇다처도 Protocol은 애매하다...