Почему использование (идентификатор) в сигнатуре метода, когда (NSObject *) было бы более точным?

Можно использовать:

 Request.Params[Control.UniqueId] 

Для получения значения управления, ПРЕЖДЕ ЧЕМ состояние отображения инициализируется (Управление. Текст и т.д. будет пуст в этой точке).

Это полезно для кода в Init.

11
задан cduhn 1 December 2009 в 21:24
поделиться

3 ответа

Использование идентификатора сообщает компилятору, что это будет объект неизвестного типа. Используя NSObject, компилятор будет ожидать, что вы будете использовать только сообщения, доступные для NSObject. Итак ... Если вы знаете, что массив был возвращен и он был приведен как id, вы можете вызвать objectAtIndex: без предупреждений компилятора. Возвращаясь с приведением NSObject, вы получите предупреждения.

8
ответ дан 3 December 2019 в 03:04
поделиться

Причина, по которой (id) используется в объявлениях методов, двоякая:

(1) Метод может принимать или возвращать любой тип. NSArray содержит любой случайный объект и, таким образом, objectAtIndex: вернет объект любого случайного типа. Преобразование его в NSObject * или id было бы неверным по двум причинам; во-первых, массив может содержать подклассы, отличные от NSObject, при условии, что они реализуют определенный небольшой набор методов и, во-вторых, конкретный тип возвращаемого значения потребует преобразования.

(2) Objective-C не поддерживает ковариантные объявления. Рассмотрим:

@interface NSArray:NSObject
+ (id) array;
@end

Теперь вы можете вызвать + array как для NSArray , так и для NSMutableArray . Первый возвращает неизменяемый массив, а второй - изменяемый массив. Из-за Objective-C ' s отсутствие поддержки ковариантных объявлений, если бы вышеупомянутое было объявлено как возвращающее (NSArray *) , клиенты метода подклассов должны были бы привести к `(NSMutableArray *). Уродливые, хрупкие и подверженные ошибкам. Таким образом, использование универсального типа, как правило, является наиболее простым решением.

Итак ... если вы объявляете метод, который возвращает экземпляр определенного класса, приведите тип явно. Если вы объявляете метод, который будет переопределен и это переопределение может вернуть подкласс и , тот факт, что он возвращает подкласс, будет доступен клиентам, тогда используйте (id) . .

Нет необходимости сообщать об ошибке - их уже несколько.


Обратите внимание, что ObjC теперь имеет ограниченную поддержку ковариации с помощью ключевого слова instancetype .

То есть NSArray Метод массива + теперь может быть объявлен как:

19
ответ дан 3 December 2019 в 03:04
поделиться

Вы уже можете вызвать -retain для указателей типа id без преобразования типов. Если вы используете определенный тип суперкласса, вам придется приводить указатель каждый раз, когда вы вызываете метод подкласса, чтобы избежать предупреждений компилятора. Используйте id, чтобы компилятор не предупреждал вас и лучше обозначал ваши намерения.

1
ответ дан 3 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: