Тип возвращаемого значения NSString stringWithFormat, почему это идентификатор?

Почему метод [NSString stringWithFormat] возвращает тип id? Судя по имени, я ожидаю, что он вернет NSString, а не общий указатель. Другие классы следуют этому «правилу». Например, [NSNumber numberWithInt] возвращает NSNumber, а не id.

Я думаю, что это даже не оправдано тем, что это что-то вроде фабричного метода.


person giampaolo    schedule 07.11.2012    source источник
comment
Для подкласса. NSMutableString в этом случае потребуется приведение.   -  person Richard J. Ross III    schedule 08.11.2012
comment
Да, я согласен — вы можете танцевать чечетку вокруг того, почему это так, как есть, но в конечном счете это не имеет смысла.   -  person Hot Licks    schedule 08.11.2012


Ответы (2)


Вы упомянули NSNumber, у него нет прямых подклассов, поэтому numberWithInt: безопасно возвращать NSNumber*

NSString* (и другие классы, такие как NSSet) возвращают тип id, потому что они могут иметь подклассы (NSMutableString и NSMutableSet соответственно), которые наследуют этот метод. Таким образом, эти унаследованные вызовы должны возвращать экземпляр типа подкласса, и из-за правил именования методов вы не можете перегружаться только на основе возвращаемого типа. Таким образом, им нужен общий тип для всех, а именно id.

Обновление. Последние изменения означают, что теперь доступно ключевое слово instancetype. Вы могли заметить, что многие ссылки на id теперь заменены на instancetype. Это ключевое слово указывает компилятору, что возвращаемый тип метода является тем же классом, что и получатель метода.

Например (и я подчеркиваю пример, это может быть не так в реальной структуре):

NSArray:
- (instancetype)initWithArray:(NSArray*)array;

NSMutableArray:
// Inherits from NSArray

----

// Receiver is NSArray, method belongs in NSArray, returns an NSArray
[[NSArray alloc] initWithArray:@[]];

// Receiver is NSMutableArray, method belongs in NSArray, returns an NSMutableArray
[[NSMutableArray alloc] initWithArray:@[]];
person WDUK    schedule 07.11.2012
comment
Хорошо, я никогда не думал, что смогу вызвать [NSMutableString stringWithFormat]. Обычно я создавал пустую NSMutableString, а затем добавлял форматы. Мое понимание иерархии классов основано на опыте Java, где String не является суперклассом StringBuilder. - person giampaolo; 08.11.2012
comment
Изменяемая версия класса всегда является подклассом своего конкретного аналога. Это имеет смысл для Cocoa, изменяемый класс идентичен конкретному, с добавлением нескольких прибамбасов, чтобы разрешить его чтение и запись, а не только чтение :) - person WDUK; 08.11.2012
comment
@WDUK придирчив, NSNumber - это кластер классов, поэтому у него много подклассов, просто они частные. - person Gabriele Petronella; 07.12.2013
comment
@GabrielePetronella Совершенно верно, но в глазах обычного разработчика вам не нужно беспокоиться о них. Только если вы должны были создать подкласс или swizzle конкретную реализацию, вам нужно было бы (что я не рекомендую с NSNumber, вы не хотите впутывать себя, возясь с его реализацией помеченного указателя!) - person WDUK; 09.12.2013

Потому что это статический метод класса NSString, и предполагается, что он возвращает тип вызываемого объекта. Это также зависит от типа, так как это может происходить из NSMutableString.

person rooster117    schedule 07.11.2012