Objective-C не нужно знать тип получателя.Во время выполнения все объекты просто id
, и все отправляется динамически.Таким образом, любое сообщение может быть отправлено любому объекту, независимо от его типа.(Во время выполнения объекты могут сами решать, что делать с сообщениями, которые они не понимают. Наиболее распространенная вещь, которую нужно сделать, это вызвать исключение и аварийный отказ, но есть много видов объектов, которые могут обрабатывать произвольные сообщения, которые не '• сопоставить непосредственно вызовам методов.)
Однако есть несколько технических деталей, которые усложняют это.
ABI (двоичный интерфейс приложения) определяет различные механизмы для возврата определенных примитивных типов.Пока значение является «целочисленным размером в слово», тогда это не имеет значения (это включает в себя такие вещи, как NSInteger
и все указатели, что означает расширение всех объектов).Но на некоторых процессорах числа с плавающей точкой возвращаются в регистры, отличные от целых чисел, и структуры (например, CGRect
) могут быть возвращены различными способами в зависимости от их размера.Чтобы написать необходимый язык ассемблера, компилятор должен знать, каким будет возвращаемое значение.
В ARC добавлены дополнительные складки, которые требуют, чтобы компилятор знал больше о типе параметров (в частности,являются ли они объектами или примитивами), и есть ли какие-либо атрибуты управления памятью, которые необходимо учитывать.
Компилятору на самом деле все равно, что такое "настоящий" тип test
, покаон может выяснить типы и атрибуты -count
.Поэтому, имея дело со значением id
, он просматривает все известные селекторы, которые он видит (то есть каждый, определенный во включенном заголовке или текущем .m
).Хорошо, если их много в разных классах, если они все согласны.Но если он вообще не может найти селектор или некоторые интерфейсы не согласны, он не может скомпилировать строку кода.
Как отмечает lobstah, у вас, вероятно, есть тип где-то в вашем Swiftкод, который имеет метод @objc
с именем count()
или свойство @objc
с именем count
, которое возвращает что-то отличное от Int
(которое сопоставляется с NSInteger
и соответствует обычной подписи -count
).Вам нужно будет исправить этот метод, или вам нужно будет скрыть его от ObjC (например, добавив @nonobjc
).
Или намного лучше: избавьтесь от id
и используйтеего актуальный тип.id
обычно плохая идея в Какао, и особенно плохая, если вы вызываете методы для него, так как компилятор не может проверить, будет ли объект реагировать, и вы можете потерпеть крах.