Причина, по которой (id) используется в объявлениях методов, состоит из двух частей:
(1) Метод может принимать или возвращать любой тип. NSArray содержит любой случайный объект и, таким образом, objectAtIndex:
вернет объект любого случайного типа. Преобразование в NSObject*
или id <NSObject>
будет некорректным по двум причинам; во-первых, массив может содержать не подклассы NSObject, если они реализуют определенный небольшой набор методов, а во-вторых, конкретный тип возвращаемого значения потребует приведения.
(2) Objective-C не поддерживает ковариантные объявления. Рассмотрим:
@interface NSArray:NSObject
+ (id) array;
@end
Теперь вы можете звонить +array
на NSArray
и NSMutableArray
. Первый возвращает неизменный массив, а второй - изменяемый массив. Из-за отсутствия поддержки в Objective-C ковариантного объявления, если бы вышеупомянутое было объявлено как возвращающее (NSArray*)
, клиенты метода подклассов должны были бы привести к `(NSMutableArray *). Гадкий, хрупкий и подверженный ошибкам. Таким образом, использование универсального типа, как правило, является наиболее простым решением.
Итак ... если вы объявляете метод, который возвращает экземпляр определенного класса, приведите тип в явном виде. Если вы объявляете метод, который будет переопределен, и это переопределение может вернуть подкласс и тот факт, что он возвращает подкласс, будет выставлено клиентам, тогда используйте (id)
.
Не нужно регистрировать ошибку - их уже несколько.
<Ч />
Обратите внимание, что теперь ObjC имеет ограниченную поддержку ковариации через ключевое слово instancetype
.
т.е. Метод массива NSArray
теперь может быть объявлен как:
+ (instancetype) array;
И компилятор будет обрабатывать [NSMutableArray array]
как возвращающее NSMutableArray*
, тогда как [NSArray array]
будет считаться возвращающим NSArray*
.