2012-04-06 1 views
15

NSObject 프로토콜은 주식 프로토콜 템플리트와 함께 제공되지만 실제 프로토콜 구현에 필요한 것만은 아닙니다. 그것을 떠나는 것은 절대적으로 변화가없는 것 같습니다. 따라서 프로토콜이 그 프로토콜을 상속해야하는 것은 정말로 필요한 것입니까 아니면 불필요한 추가 기능입니까?필수 프로토콜은 NSObject 프로토콜을 준수합니까?

답변

19

에 준수 모르는

@interface NSObject <NSObject> { 
    Class isa; 
} 

로 정의 (와 같은 많은있다 나) 우리의 프로토콜을 <NSObject>과 일치시키지 않았다. 그것은 잘 작동합니다. 그러나 그것은 종종 성가심 일 수 있습니다. 가장 일반적인 성가심은 respondsToSelector:NSObject* (프로토콜의 모든 부분을 무력화시키는 종류)으로 다시 캐스팅하지 않고 사용할 수 없다는 것입니다. 그것은이 없었기 때문에 ObjC1 시대에는 문제가되지 않았기 때문에 아무도 우리가 걱정하지 않았습니다. (@optional 없이는 그다지 유용하지 않았기 때문에 프로토콜을 많이 사용하지 않았습니다.) 그런 다음 ObjC2가 옵션 메소드의 놀라운 추가와 함께 갑자기 respondsToSelector:이 중요시되었습니다. 우리의 느린 시간은 조금 걸렸지 만 결국 프로토콜이 <NSObject>을 따르게되면 인생이 훨씬 더 간단 해 졌음을 알기 시작했습니다. 조심스럽게 Xcode에이 기능이 추가되어 누구나보다 편리하게 작업을 수행 할 수있게되었습니다.

아니요, 아니요. 많은 경우에 문제가되지 않습니다. 그러나 그렇게하지 않는 이유는별로 없기 때문에 나는 그것을 추천한다.

+0

훌륭한 답변 ... NSObject 프로토콜로 언급하는 성가심조차도'id obj'로 시작됩니다. 왜냐하면 클래스로 객체를 참조하면 컴파일러가 상속을 알 수 있기 때문입니다. 아마도 NSObject로 시작합니다 ... –

6

반드시 그렇지는 않습니다. 델리게이트는 도우미 객체 일뿐입니다. 요구 사항은 위임 클래스가 요구하는 것입니다. 주어진 대리인의 요구 사항을 공식화하려면 정식 프로토콜 즉, @protocol 지시어를 사용하여 프로토콜을 선언하십시오. NSObject의 프로토콜을 준수하는 것은 이러한 요구 사항 중 하나 인 경우에, 당신은 당신의 프로토콜을 채택 할 수 있습니다 말했다

@protocol MyDelegateProtocol <NSObject> 
//... 
@end 

, 나는 아마 NSObject의 또는 NSProxy에서 파생 된 아니에요 대리자를 만들 수있는 어떤 이유가 표시되지 않습니다, 이 두 클래스는 이미 NSObject 프로토콜을 준수합니다.

+0

NSObject에서 파생 된 대리인이 프로토콜이 NSObject를 준수하지 않으면 중단 될 수 있습니까? (즉, 델리게이트 메소드가 호출되지 않기 때문에 일반적으로 적합하지 않습니까?) – CodaFi

+2

NSObject는 NSObject 프로토콜을 따르므로 NSObject에서 파생 된 클래스도 NSObject 프로토콜을 준수합니다. NSObject에서 파생 된 델리게이트는 NSObject 프로토콜을 명시 적으로 채택하지 않기 때문에 중단되지 않습니다. – Caleb

1

모든 객체가 서브 클래스 NSObject에 있어야하는 것은 아니므로 그러한 객체가 사용자의 프로토콜을 준수 할 것으로 기대한다면 NSObject를 준수 할 필요는 없습니다.

NSObject 준수 객체가 기본을 준수 함을 컴파일러에서 알 수 있습니다. NSObject Protocol Reference을 확인하십시오. 내가 NSObject를 준수한다고 말하지 않고 어떻게 컴파일러가이 중 하나에 부합하는지 알 수 있습니까?

NSObjectid

typedef struct objc_object { 
    Class isa; 
} *id; 

로 정의되는 반면, 그래서 id의 컴파일러가 몇 년 전 들어 NSObject

1

권장 사항이며 필수 사항은 아닙니다. 애플의 공식 문서 ProgrammingWithObjectiveC.pdf에 따르면

이 위에 정의되어 당신이 프로토콜을 준수하는 id를 에 respondsToSelector: 메소드를 호출하려고하면 컴파일러 오류가 발생합니다 그것을위한 알려진 인스턴스 메소드가 없다는 것입니다. 에 프로토콜로 ID를 부여하면 allstatic 유형 확인이 다시 시작됩니다. 지정된 프로토콜에 정의되지 않은 메소드를 호출하려고하면 오류가 발생합니다. 컴파일러 오류를 방지하는 한 가지 방법은 사용자 지정 프로토콜이 NSObject 프로토콜을 채택하도록 설정하는 것입니다.

상기 정의 된 것 같은 프로토콜 NSObject 프로토콜을 따르는없는 프로토콜이다. 이 채택 NSObject의 클래스, 예를 들어

, 그것은 NSObject의 프로토콜합니다 (NSObject의 행동 중 일부는 별도의 프로토콜에 에서의 클래스 인터페이스를 분할에 을 준수하기 위해 프로토콜을 정의하는 가장 좋은 방법입니다 NSObject 프로토콜).