Взгляните на блок методов создания NSArray в NSArray.h.
Есть ли законная причина для методов, возвращающих id, чтобы не возвращать instancetype?
Apple даже предприняла попытку добавить встроенные комментарии, чтобы сообщить нам, что id
в этом случае возвращает NSArray.
@interface NSArray (NSArrayCreation)
+ (instancetype)array;
+ (instancetype)arrayWithObject:(id)anObject;
+ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+ (instancetype)arrayWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)arrayWithArray:(NSArray *)array;
- (instancetype)init; /* designated initializer */
- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; /* designated initializer */
- (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithArray:(NSArray *)array;
- (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;
+ (id /* NSArray * */)arrayWithContentsOfFile:(NSString *)path;
+ (id /* NSArray * */)arrayWithContentsOfURL:(NSURL *)url;
- (id /* NSArray * */)initWithContentsOfFile:(NSString *)path;
- (id /* NSArray * */)initWithContentsOfURL:(NSURL *)url;
@end
Единственное, что я мог придумать с помощью этих конкретных методов, - это руководство от Apple
"Представление массива в местоположении, идентифицируемом aURL, должно содержать только список свойств > объекты (объекты NSString, NSData, NSArray или NSDictionary). Объекты, содержащиеся в этом массиве, являются неизменяемыми, даже если массив изменен".
Однако, это все еще для меня не объясняет использование id над instancetype, поскольку они все же позволяют NSArray sublclasses возвращать свои собственные instancetype
NSDictionary следует точно такой же схеме, где при создании словаря с содержимым файла или URL-адреса используется id
, а во всех других методах создания используется instancetype
- (instancetype)initWithObjectsAndKeys:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary;
- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary copyItems:(BOOL)flag;
- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+ (id /* NSDictionary * */)dictionaryWithContentsOfFile:(NSString *)path;
+ (id /* NSDictionary * */)dictionaryWithContentsOfURL:(NSURL *)url;
- (id /* NSDictionary * */)initWithContentsOfFile:(NSString *)path;
- (id /* NSDictionary * */)initWithContentsOfURL:(NSURL *)url;
Я знаю, что Apple просто начинает заменять id
в базовых классах на instancetype
, но характерные несоответствия в ее использовании в рамках отдельных классов действуют как руководство для нашего собственного использования, или они просто не обошли стороной к завершающим занятиям, над которыми они начали работать?
чтобы развернуть только немного, я хотел изучить тип возвращаемого значения dictionaryWithContentsOfFile
при вызове в NSMutableDictionary
NSString * plistPath = [[NSBundle mainBundle] pathForResource:@"myFile" ofType:@"plist"];
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
if ([ myDictionary isKindOfClass:[NSMutableDictionary class]])
{
NSLog(@"This is a mutable dictionary why id and not instancetype?");
[myDictionary setObject:@"I can mutate the dictionary" forKey:@"newKey"];
}
NSLog (@"%@", myDictionary[@"newKey"]);
return YES;
}
На мою консоль выводилось следующее:
Это изменчивый словарь, почему id, а не instancetype?
Я могу изменить словарь
Поэтому я могу добавить в словарь новые ключи и объекты.