2012-01-06 2 views
6

프로토콜에 대한 지시어는 @selector와 마찬가지로 @protocol이지만 프로토콜 (예 : @Selector의 SEL)을 참조하기위한 "유형"은 무엇입니까? MacOSX 스택에서는 Protocol *입니다.Objective-C에서 프로토콜을 참조하는 방법?

id<TheNameOfTheProtocol> aVariableToThatProtocol; 

또는 메시지가 (Protocol *) 개체를 원하는 경우 :

[myObject conformsToProtocol:@protocol(TheNameOfTheProtocol)]; 

답변

13

당신은 그것을 참조?

나는 사과의 공식 DOC이라고하며, 이 프로토콜에서 다른 프로토콜를 참조하는 간단한 예를 발견

#import "B.h" 

@protocol B; // To break the recursive cycle, you must use the @protocol directive to make a forward reference to the needed protocol instead of importing the interface file where the protocol is defined 

@protocol A 
    - foo:(id <B>)anObject; 
@end 

프로토콜 B는 다음과 같이 선언한다 :

#import "A.h" 

@protocol B 
    - bar:(id <A>)anObject; 
@end 

@protocol 지시문을이 방식으로 사용하면 컴파일러에 B가 나중에 정의 할 프로토콜임을 알리는 것에 유의하십시오. 프로토콜 B가 정의 된 인터페이스 파일을 가져 오지 않습니다. 당신이 원하는


그리고 바로 여기에 더 가지에 대한 알고 : 여러 가지면에서

이 프로토콜은 클래스 정의와 유사하다. 둘 다 메소드를 선언하고 런타임에 클래스의 인스턴스별로 클래스를, 프로토콜의 인스턴스별로 프로토콜을 객체로 나타냅니다. 클래스 객체와 마찬가지로, 프로토콜 객체는 소스 코드에서 발견되는 정의와 선언으로부터 자동으로 생성되며 런타임 시스템에서 사용됩니다. 프로그램 소스 코드에 할당되고 초기화되지 않았습니다.

소스 코드는 여기 후행 괄호 세트가 제외 @protocol() 지시자 프로토콜을 선언 -THE 동일한 지시어를 사용하여 프로토콜 개체를 참조 할 수있다.

Protocol *myXMLSupportProtocol = @protocol(MyXMLSupport); 

이 소스 코드는 프로토콜 개체를 연상 할 수있는 유일한 방법은 다음과 같습니다 괄호는 프로토콜 이름을 묶습니다. 클래스 이름과 달리 프로토콜 이름은 @protocol() 내부를 제외하고 객체를 지정하지 않습니다.


그리고 무엇보다의 는 그것을 conformsToProtocol: 메시지를 전송하여 객체가 프로토콜 준수 여부를 확인할 수 있습니다 :

if (! [receiver conformsToProtocol:@protocol(MyXMLSupport)] ) { 
    // Object does not conform to MyXMLSupport protocol 
    // If you are expecting receiver to implement methods declared in the 
    // MyXMLSupport protocol, this is probably an error 
} 

conformsToProtocol : 테스트 같은입니다 respondsToSelector : 프로토콜이 채택되었는지 테스트하는 것을 제외하고는 단일 메소드를 테스트합니다 (그리고 아마도 모든 메소드가 구현되었는지 여부가 아니라 구현 된 것으로 선언 된 메소드). 프로토콜의 모든 메서드를 검사하므로 conformsToProtocol :respondsToSelector :보다 더 효율적일 수 있습니다.

conformsToProtocol : 테스트는 isKindOfClass 같이도이다 테스트는 그것이 프로토콜보다는 상속 계층에 기초한 유형에 따라 타입 테스트를 제외하고있다.

+0

그냥 궁금해서, 프로토콜 "유형"에 "ID로 사용되어야합니다 어떤 이유 ? " C# 백그라운드에서 오는 인터페이스 참조는 클래스 참조 (예 : IP 프로토콜 프로토콜)와 유사하므로 인터페이스 참조를 시각화하는 것이 약간 쉽습니다. – 5StringRyan

+0

@ 5StringRyan 추론을 모르겠지만 NSObject가 아니더라도 'id'유형은 모든 객체의 일반적인 유형입니다. 이 구문의 한 가지 장점은 여러 프로토콜을 허용한다는 것입니다. 'id '행을 따라 무언가를 할 수 있습니다. 객체가 두 프로토콜을 모두 준수한다는 것을 나타냅니다. 또는 귀하의 프로토콜이 NSObject를 따르지 않지만 참조하는 클래스 인스턴스가 있다면 'id '를 수행 할 수 있습니다. –

+3

@ 5StringRyan 타입은'id' 일 필요는 없습니다. 예 :'NSArray * var = [NSArray array];'는 합법적으로 유용합니다. 당신은 또한'NSArray * var = [NSArray array];'sooo ...라고 쓸 수 있습니다. 이것은 확실히 타입 안전성을 주입하는 좋은 방법입니다. (예제는 어리석은 - 그들은 단지 구문을 보여줍니다) – justin

4

id <YourProtocol> delegate (프로토콜을 참조하는 데 사용됩니다)

2

이 OS의 X에서와 동일합니다 :

Protocol * p = objc_getProtocol("UITableViewDataSource"); 

그것은 <objc/runtime.h>에 선언 된 것 :

typedef struct objc_object Protocol;