문제

Objective-C는 동적 바인딩을 사용합니다.즉, 메서드 호출이 런타임에 해결됩니다.

괜찮은.

그리고 점 표기법의 사용은 실제로 메소드 호출로 귀결됩니다.

그런데 왜 다음과 같은 일을 할 수 없습니까?

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


  // Intercept the exception
  @try
  {
    @throw [ NSException 
            exceptionWithName:@"Exception named ME!" 
            reason:@"Because i wanted to" 
            userInfo:nil ] ;
  }
  @catch( id exc ) // pointer to an exception object?
  {



    //NSLog( @"%@ : %@\n", exc.name, exc.reason ) ; // 불법적인:구조 나 노조가 아닌 멤버 // '이름'요청..
    // If objective-c uses dynamic binding, and dot notation
    // boils down to calling the getter, then
    // WHY do I have to cast to the concrete type here?

    // Only works if I cast to the concrete type NSException*
    NSException* nexc = (NSException*)exc ;
    NSLog( @"%@ : %@\n", nexc.name, nexc.reason ) ;



  }



  [pool drain];
    return 0;
}

"동적 바인딩"이라는 말을 들으면 "그래서 스크립트 언어처럼 작동해야 한다"고 생각합니다. 그리고 JavaScript와 같은 스크립팅 언어에 비해 Objective-C가 얼마나 유연하지 못한지 놀랐습니다.

도움이 되었습니까?

해결책

런타임과 컴파일러를 혼동하고 있습니다.런타임에서는 이에 대처하는 데 아무런 문제가 없습니다.문제는 점 표기법(구문적 설탕)이 Objective-C 개체와 C 구조체를 명확하게 구분하기 위해 컴파일러에 대한 유형 정보가 필요하다는 것입니다.

점 표기법을 사용하지 않으면 작동합니다.

NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;

위의 내용은 유형이 id가 아닌 경우 경고를 생성합니다. 왜냐하면 컴파일러는 유형을 알고 있고 디스패치가 작동할 것이라고 보장할 수 없지만 컴파일하고 실행하기 때문입니다.

근본적으로 당면한 문제는 컴파일러가 구조 로드 또는 Objective C 디스패치를 ​​생성할지 여부를 알아야 한다는 것입니다. 즉, 점 표기법을 사용하면 객체와 스칼라 유형 간의 차이를 결정하는 데 충분한 정보가 필요합니다.

다른 팁

동적 바인딩 동의어가 아닙니다 동적 타이핑. C는 강력하게 입력 된 언어이며, 특히 인수 또는 반환 값의 유형이 중요하며 코드 생성에 크게 영향을 줄 수 있습니다.

특성은 구체적으로 모호성을 제거하도록 설계되었습니다. 그 일부로서, 결정은 ~ 아니다 도트 구문을 사용하도록 허용하십시오 id.

구체적 으로이 상황을 해결합니다.

@interface Foo
- (short) length;
@end

@interface Bar
- (unsigned long long) length;
@end

위의 두 개의 별도 헤더 파일에서 [anObject length] 경고를 줄 것입니다 두 헤더 파일 중 하나만 가져 왔습니다. 하나의 헤더 파일 만 가져 오면 호출 사이트가 컴파일되어 헤더에 표시된 유형을 반환합니다. 전화 사이트가 다른 방법, 예상치 못한 결과가 반환됩니다.

DOT 구문의 한계는 이러한 잠재적 모호성을 제거합니다. 이것이 당신이 이유이기도합니다 ~하지 않다 일반적으로 방법에 대한 공동 변수 선언을 참조하십시오. C ABI는 단지 그것을 깨끗하게 지원하지 않습니다 (즉, Objective-C는 객체 유형 공동 분위기를 지원하는 일이 좋지 않습니다).

실제로 대상 C 개발자는 거의 사용하지 않습니다 id 유형. 특정 유형 선언을 사용하면 컴파일러가 코드 검증을 크게 향상시킬 수 있습니다.

Objective-C는 동적 바인딩을 지원합니다. 그러나 'ID'유형의 객체에서 속성을 사용할 수는 없지만 원하는 메시지를 보낼 수 있습니다. (이것은 아마도 현재의 정의/구현에서 실수 일 것입니다 ...하지만 지금은 그것을 옆으로 두자.)

당신이했다면

NSLog(@"%@ : %@", [exc name], [exc reason] ); 

그러면 작동합니다. 어쨌든 별도의 라인에 있으므로 NSLOG 문에 NewLine을 넣을 필요가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top