Если вы хотите, чтобы компилятор предупреждал вас, приведите объект, возвращенный -copy
, к ожидаемому вами типу, например,
[(NSHour *)[self.H1time copy] stringValue]
(кстати, я бы не использовал NSпрефикс для моих классов, так как это префикс, используемый Apple.)
Как уже говорили другие, -copy
объявляется как возвращающее значение типа id
.Поскольку id
обозначает универсальный объект, компилятор не имеет никакой информации о том, на какие селекторы может возвращаться возвращаемое значение.Он знает, что существует селектор stringValue
(потому что несколько классов Какао объявляют методы -stringValue
), поэтому он принимает это.
Но я переопределил -copyWithZone:
, чтобы вернуть NSHour *!
И это правильно, если вам нужно пользовательское поведение копирования, поскольку -copy
- это просто удобный метод, который вызывает -copyWithZone:
.Однако, как указано выше, ваш код вызывает -copy
, который не был переопределен для возврата NSHour *
.
Что если я также переопределю -copy
, чтобы он возвращал NSHour *?
Тогда компилятор узнает об этом и предупредит вас в случае, если вы пытаетесь отправить сообщение, содержащее селектор, у которого нет соответствующего метода в NSHour
.
Должен ли я сделать это?
Ну, по большей части, не совсем.
Вы когда-нибудь задумывались, почему все примеры переопределения -init
возвращают id
вместо класса?тип?Это происходит потому, что среда выполнения Objective C создает единственное описание метода для данного селектора.Следовательно, методы в разных классах, имеющие одинаковые селекторы (т. Е. Одинаковые имена методов), должны использовать одни и те же типы аргументов и возвращаемые типы.
Таким образом, с точки зрения времени выполнения селектор init
описывается как метод сэто имя и тип возвращаемого значения id
.Аналогично, селектор copy
описывается как метод с таким именем и типом возврата id
.Если вы повторно используете имя селектора в методах с различными типами возвращаемых значений или типами аргументов, вы путаете систему времени выполнения, что может привести к сбою или искажению данных.
При этом, когда вы статически печатаетеваши объекты, вы даете информацию компилятору, чтобы он знал, какие методы доступны, и он будет использовать соответствующие методы независимо от методов в других классах, имеющих разные типы возвращаемых данных и типы аргументов.
Эта тема на сайте cocoabuilder.com содержит больше информации по этому вопросу, включая ответ Грега Паркера, который работает над средой выполнения Objective-C.