На самом деле полиморфизм работает, как и ожидалось. Если бы это не сработало, ничего бы не было напечатано (в вашем примере печатается 0,0000). Дело в том, что, хотя ваш экземпляр фактически отвечает на сообщение testFloat:10.0f
, поскольку компилятор не может статически видеть объявление метода (так как класс UIView
не объявляет такой метод), он предполагает, что ваш метод принимает ...
в качестве аргумента и возвращает id
.
Когда CGFloat
передается методу, который ожидает переменное число аргументов (...
), он переводится в double
. Таким образом, получающему методу передается аргумент double
, и он считает, что это float
, и он не печатается правильно.
Вы можете проверить это поведение, изменив строку NSLog
на:
NSLog(@"%f", *(double*)&x);
Когда компилятор отправляет сообщение FloatView*
, а не UIView*
, он может найти точную сигнатуру метода. Он может видеть, что действительно ожидает CGFloat
и не продвигает аргумент к double
. В результате все работает правильно.
Кроме того, если UIView*
содержит объявление метода, которое принимает CGFloat
, компилятор будет вызывать метод соответствующим образом. Подводя итог, это не проблема полиморфизма; это проблема с отсутствующей подписью метода.