2011-01-13 5 views
1

속성 구문을 사용하는 컴파일은 컴파일 타임에 수신기 유형을 알아야합니다. 내가 뭔가를 이해하지 못할 수도 있지만 Objective-C가 동적 인 언어라는 점을 감안할 때 이것은 깨진 또는 불완전한 컴파일러 구현처럼 보입니다.컴파일 할 때 속성에 명시 적으로 타이핑해야하는 이유는 무엇입니까?

속성 "주석이"로 정의됩니다

@property (nonatomic, retain) NSString *comment; 

및 합성 :

"문서"에 부합 몇 가지 클래스 중 하나의 인스턴스입니다 :

@protocol DocumentComment <NSObject> 

@property (nonatomic, retain) NSString *comment; 

@end 

으로 간단히 표시됩니다.

,
id document; 

다음 속성 신택스를 사용하는 경우 :

stringObject = document.comment;  

다음 에러가 GCC에 의해 생성된다 : 그러나

error: request for member 'comment' in something not a structure or union 

다음 동등한 수신기 방식의 구문, 경고 또는 에러없이 컴파일 런타임에 예상대로 잘 작동합니다.

stringObject = [document comment]; 

왜 등록 정보에서 컴파일 타임에 수신자 유형을 알아야하는지 이해할 수 없습니다. 제가 누락 된 것이 있습니까? 수신 객체가 동적 유형을 갖는 상황에서 오류를 피하기 위해 후자의 구문을 사용하기 만합니다. 반쯤 구운 것 같습니다.

답변

4

속성 액세스를 컴파일하려면 속성 이름을 올바른 getter/setter 이름으로 변환하는 방법을 알아야합니다. 속성이 선언의 일부로서 이름을 재정의 수 있으므로 수신기의 유형을 모른 채, 컴파일러는 아마도과 같이, 게터/세터라는 것을 알 수 없습니다

@property (nonatomic, retain, getter=myComment) NSString *comment; 

를 컴파일러가 있다면 계속해서 타입이 지정되지 않은 예제 코드를 생성하면 [document comment]이 생성되어 런타임에 올바르게 생성 된 코드가 실제로는 [document myComment]이므로 실패합니다.

+0

하지만 런타임에는 문서의 실제 유형을 알지 못하지만 표준 수신기 방법 구문을 사용하여 성공합니다. 이것은 역동적 인 언어입니다. 물론 document.comment 속성은 사용자가 제공 한 속성 선언과 함께 실패하므로 완벽한 의미를 갖습니다.컴파일러는 리시버 메소드 구문 예제와 동일한 정보 부족을 가지고 있지만 컴파일러는 그대로 사용합니다. 존재하지 않는 메서드 이름을 사용할 수 있으며 컴파일러는이를 그대로 둡니다. – ctpenrose

+0

컴파일은 객체에 -comment라는 메서드가 어딘가에 있다는 것을 알면 불만없이'[document comment]'만을 받아 들일 것입니다. '[document sdlkjf]'라고 입력하면 경고 메시지가 나타납니다. 그러나 당신은 정확합니다. 동적 디스패치를 ​​사용하는 메소드는 객체가 실제로 그 메시지를 처리하지 않으면 런타임에 만 실패합니다. 반면에 속성은 컴파일 타임 기능이므로 속성 액세스는 컴파일 타임에 해결됩니다. –

+1

... 만약'NSString *', 하나의'char *'그리고 하나의 구조체를 반환하는 3 개의'comment' 메소드가 있다면, 모든 다이내믹은 어쨌든 창 밖으로 나옵니다. 현실은 Objective-C가 정적 디스패치 또는 다형성 방식으로 정적 유형 지정을받지 않고 정적으로 형식이 지정된 언어라는 사실입니다. – bbum

3

케빈이 증상 중 하나를 범했습니다.

속성을 디자인 할 때 id을 도트 구문의 대상으로 사용하기 위해 이 아닌이 매우 구체적인 결정을 내 렸습니다. Kevin이 지적한 애매 모호한 것 이외에, 모두 (ID) 수신기와 관련된 모호성을 피하는 욕구가 바람직한 것으로 간주되었습니다.

일반적으로 완전히 규정되지 않은 id을 사용하면 바람직하지 않으며 적극적으로 권장하지 않습니다. 언어로 새로운 기능을 만들 때 id을 지원하지 않으면 새로운 기능에서 코딩 패턴이 깨지기 쉽습니다.

+0

에 대한 호출을 안전하게 내보낼 수 없습니다. 동의하지 않습니다. 비대칭 정적 유형 지정 기능을 추가합니다. 속성을 사용할 때 구문 적으로 언어의 유용한 동적 특징을 상쇄합니다. 나는 원래 Stepstone 건축가가 이것에 관해 무엇을 말할 것인지 궁금합니다. 일부는 재산과 완전히 싸울 수도 있습니다. 나는 그들의 편리함을 좋아하지만, 비대칭 성은 여러 특정 상황에서 실망 스럽다. 프로토콜은 소위 말하는 "연약한 코딩 패턴"을 제거하는 데 사용될 수 있습니다. – ctpenrose

+0

정적 타이핑은 나쁜 것은 아닙니다. 나는 Obj-C가 다이나믹 타이핑과 정적 타이핑 사이에 꽤 좋은 균형을 이루었다 고 생각한다. 속성은 꽤 많은 컴파일 타임 기능입니다 (런타임에 영향을주는 유일한 방법은 런타임 메서드를 통해 메타 데이터를 사용할 수 있다는 것입니다). 따라서 정적 유형 지정 작업에 빠지게됩니다. –

+0

Brad Cox는 실제로 언어가 취한 방향을 좋아합니다. 나는 당신의 비판이 어디에서 왔는지 이해하지만, 충분히 역동적 인 타이핑에 의해 함축 된 허약성을 초래할만큼 충분히 큰 범위에는 적용 할 수 없다고 생각합니다. 꽤 오래 전에 - 1996ish, 또는 그렇게 IIRC - 가능한 한 많이 일반 타이핑에서 벗어나려는 결정이 내려졌습니다. 특정 문제가있는 패턴이있는 경우 버그를 신고하거나 SO 질문을하십시오. – bbum

관련 문제