Basic Cocoa newbie question here ... Это похоже на очень распространенный образец в Cocoa. Почему методы init и методы создания автореализованных объектов, такие как [NSArray arrayWithObjects: ...]
, возвращают id
? Почему возвращается NSArray *
(или создаваемый тип) не во всех отношениях лучше?Почему NSArray arrayWithObjects и друзья возвращают id, а не NSArray *?
ответ
Другая причина заключается в наборе селекторного соответствия возвращаемого значения. Если [NSArray arrayWithObjects: ...]
вернул NSArray
(по заявлению), то NSMutableArray
нужно будет повторно объявить arrayWithObjects:
с другим типом возврата (иначе вы получите предупреждение при записи NSMutableArray * a = [NSMutableArray arrayWithArray:]
).
Даже если вы пошли по этому маршруту, цепочка сообщений может быстро привести к неоднозначности, когда компилятор пытается сопоставить селекторы с типами/не-типами. Таким образом, в этом сценарии должны совпадать данные о возврате и параметрах выбора. Следовательно, используется тип возврата id
.
Если вы попытались построить строго типизированную иерархию objc с такими конструкторами и использовать высокий уровень предупреждения, вы увидите, как разворачивается эта двусмысленность. Конечно, пример NSArray/NSMutableArray достаточен для описания проблемы.
init
методы возвращают id
, чтобы они могли возвращать тот же класс, что и его суперкласс.
Классы Objective-C возвращают id
, поскольку они могут хранить объекты Objective-C любого типа.
См. Мои комментарии к ответам Джастина относительно ковариантных типов возврата –
@ Jean-PhilippePellet No Objective-C не поддерживает ковариантные типы возврата. См. Этот вопрос SO: http://stackoverflow.com/questions/2433504/why-does-gcc-warn-about-incompatible-struct-assignment-with-a-self-super-ini – trojanfoe
ОК, поэтому мой последующий вопрос : почему он не должен возвращать 'instancetype' вместо' id'? –
Искренне оно возвращает NSArray/NSMutalbeArray/что угодно.
Именно это id является общим возвращаемым значением init. Таким образом, возвращаемое значение объявляется как id, но это NSArray, который возвращается.
Но, честно говоря, я не могу дать вам никакого хорошего ответа на ваш вопрос «почему». Когда когда-либо я перезаписываю методы init в подклассе, я позволяю им возвращать ABC *, если имя класса - ABC. И это просто отлично работает.
Кажется, что нет проблем с 'init' и некоторые другие специальные методы, потому что [clang рассматривает их специально и автоматически вставляет тип возвращаемого типа instancetype] (http://clang.llvm.org/docs/LanguageExtensions.html#objc_instancetype). –
Это означает, что явным образом заявляю, что класс, который я реализую, не вызывает проблемы напрямую, но может вызвать трудности, если класс, который я сейчас разрабатываю, подклассифицируется позже. –
- 1. [NSArray arrayWithObjects: nil, nil]
- 2. NSArray arrayWithObjects и неопределенные переменные
- 3. Почему NSArray arrayWithObjects требует конечного нуля?
- 4. iPad большой NSArray - initWithObjects против ArrayWithObjects
- 5. NSArray arrayWithObjects: ограничено до девяти объектов
- 6. подробно текст эквивалентно tableData = [arrayWithObjects NSArray: - IOS
- 7. NSArray сортировка благодаря другому NSArray
- 8. Сортировка NSArray и возврат NSArray?
- 9. stringWithFormat и NSArray
- 10. deallocating NSArray Vs release NSArray
- 11. Почему методы allKeys и allValues NSDictionary возвращают NSArray, а не NSSet?
- 12. NSArray изображений и NSArray текста в UIPickerView
- 13. Редактирование автозаполнения в XCode 4. Добавление]; автозаполнение + [NSArray arrayWithObjects:
- 14. NSArray создания NSArray
- 15. NSArray и «If-statement»
- 16. NSLog NSArray в NSArray
- 17. Я создал экземпляр NSArray, тогда как его класс не NSArray, а __NSArrayI?
- 18. Многомерный NSArray для NSArray?
- 19. Сохранение аргумента NSArray - почему?
- 20. Различия между [NSArray arrayWithArray:] и [NSArray copy]
- 21. Как объединить два NSArray
- 22. NSArray фильтрация
- 23. Свифт: «NSArray?» не конвертируется в «NSArray»?
- 24. Сравнение NSArray и NSInteger
- 25. Комбинации различных объектов NSArray
- 26. Как создать NSArray из NSArray
- 27. NSArray в NSArray AddObject Строка
- 28. NSArray arrayWithObjects нуждается в нуле в конце, NSString stringWithFormat и NSLog() этого не делают. Зачем?
- 29. NSDictionary allKeys возвращает NSArray, а не NSSet
- 30. Почему NSArray имеет метод indexOfObjectPassingTest, а не объектыPassingTest, например NSSet?
Java и C++ позволяют переопределенным методам иметь ковариантные типы возврата. Тогда у цели нет такой вещи? –
@ Jean-PhilippePellet не рекомендуется использовать этот письменный стиль, особенно если вы имеете дело с объектами без объекта objc. весь необходимый вам динамизм существует, но у компилятора есть сложные типы совпадений типов/селекторов/возвращаемых типов. селектор objc не определяет типы возвращаемых данных или типы параметров (хотя они могут быть запрошены о конкретных реализациях), и отправка всегда динамическая. потому что диспетчирование является динамическим, вы также должны использовать параметр выбора и возвращаемые типы для соответствия. он действительно работает на практике. '[NSMutableArray array]' явно возвращает 'NSMutableArray'. – justin
@ Jean-PhilippePellet (продолжение) несмотря на (исходный уровень) стирание стилей, хотя 'id'. и trojanfoe связало очень хорошее объяснение от bbum. конечно, вы можете попробовать, но инициализаторы и конструкторы, как правило, однострочные, поэтому вы сразу же вводите этот тип, используя объявление переменной. – justin