2012-08-02 2 views
0

이것은 약간의 이전 질문에서에 따르에 응답하지만 알 수 없습니까?

for(id <stuffieProtocol> eachObject in stuffieArray) { 
    if([eachObject respondsToSelector:@selector(secretID)]) [eachObject secretID]; 
} 

위를 그들은 방법에 반응하는지 확인하기 위해 NSArray 및 검사에서 개체의 수를 취 빠른 열거 루프에서 선입니다 secretID. 메서드 secretID@protocol의 일부가 아니며 컬렉션의 개체 중 하나에 정의 된 메서드입니다.

컴파일러는 괜찮 "No known instance method for selector secretID"이 ID는 상관하지 않는다라고하고, 방법은 내가 정의 않는 유형에 각 개체를 캐스팅하여이 문제를 해결할 수 <stuffieProtocol>에 정의되어 있지 않기 때문에 if 문은 위의 실패 secretID:

if([eachObject respondsToSelector:@selector(secretID)]) [(Ted *)eachObject secretID]; 

제 질문은 원래 코드에 있습니다. 은 secretID이라는 메서드에 응답하지만 컴파일러는 그 메서드를 호출 할 때 "알려진 메서드가 없습니다"라는 것을 알게 된 이유는 무엇입니까?

+0

''Ted * '로 변환하면 불안해집니다. 나는'id'로 던지기를 원합니다. 그렇지 않으면 객체가'secretID'에 응답하면'Ted'의 인스턴스 여야한다는 것을 암시 적으로 문서화합니다. 항상 진실을 유지하는 것은 아니며 잠재적으로 거짓말을함으로써 컴파일러를 잠잠히하려고합니다. 컴파일러가 메서드를 선언하는 헤더를 볼 수 있다면 'id'로 캐스팅하는 것이 좋습니다. 'Ted' 클래스처럼'secretID' 메소드를 선언 한 클래스를 가져 왔습니다. –

답변

2

컴파일러는 개체가 해당 선택기에 응답하는지 여부는 알지 못하지만 런타임은 그렇지 않습니다. (즉, 컴파일러는 코드를 실행하지 않습니다.) 컴파일러는 모든 NSObject가 respondsToSelector:에 응답 할 수 있는지만을 고려합니다.

+0

아아, 내가 (Ted *)를 추가하면 컴파일러에게 "secretID"가 구현 된 곳을 알 수 있으며 respondsToSelector :는 런타임까지 실행되지 않습니다. – fuzzygoat

관련 문제