문제

오늘 이상한 문제를 발견했습니다.UIView의 하위 클래스를 만들고 xcode에서 제공하는 템플릿 코드에 메서드 1개만 추가했습니다.

@interface FloatView : UIView {

}
- (void)floatTest:(CGFloat)x;
@end

- (void)floatTest:(CGFloat)x {
  NSLog(@"float was %f", x);
}

그런 다음 내 appDelegate에 다음과 같은 코드가 있습니다.

UIView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];

아주 간단하죠?이것은 무엇을 인쇄해야합니까?나는 "10.0000"과 같을 것이라고 생각했지만 아니요, "0.000000"을 인쇄합니다.

나는 내가 뭘 잘못하고 있는지 알아내려고 몇 시간 동안 씨름한 다음 appDelegate의 코드를 다음과 같이 변경했습니다.

FloatView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];

그런 다음에야 예상된 "10.0000"이 인쇄되었습니다.왜 그럴까요?FloatView를 UIView의 하위 클래스로 선언했습니다. 문제 없이 FloatView 개체를 UIView 포인터에 할당할 수 있어야 하지 않습니까?

floatView가 UIView에 대한 포인터로 선언되었지만 실제로는 floatView이고 floatTest 메시지를 처리할 수 있어야 합니까?내가 여기서 완전히 벗어난 걸까요?

도움이 되었습니까?

해결책

실제로 다형성은 예상대로 작동합니다.작동하지 않으면 아무 것도 인쇄되지 않습니다(귀하의 예에서는 0.0000이 인쇄됩니다).문제는 인스턴스가 실제로 응답하는 동안 testFloat:10.0f 메시지는 컴파일러가 메서드 선언을 정적으로 볼 수 없기 때문입니다(예: UIView 클래스는 그러한 메소드를 선언하지 않습니다), 귀하의 메소드가 다음을 수행한다고 가정합니다. ... 인수 및 반환으로 id.

언제 CGFloat 가변 개수의 인수를 예상하는 메서드에 전달됩니다(...), 다음으로 승격됩니다. double.따라서 수신 메소드는 다음과 같이 전달됩니다. double 논쟁을 벌이고 그것이라고 생각한다. float 그리고 제대로 인쇄되지 않습니다.

다음을 변경하여 이 동작을 확인할 수 있습니다. NSLog 행 :

NSLog(@"%f", *(double*)&x);

컴파일러가 메시지를 보낼 때 FloatView* 보다는 UIView*, 메소드의 정확한 서명을 찾을 수 있습니다.정말 기대되는 걸 알 수 있죠 CGFloat 그리고 그 주장을 홍보하지 않습니다 double.결과적으로 올바르게 작동합니다.

추가적으로 만약에 UIView* 다음을 수행하는 메서드 선언이 포함되어 있습니다. CGFloat, 컴파일러는 메서드를 적절하게 호출합니다.요약하면 이는 다형성 문제가 아닙니다.메소드 서명 문제가 누락되었습니다.

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