Мне интересно, почему Apple использует (довольно сильно в CoreAnimation, но где-то еще) константы, объявленные как NSString * const
, например, kCAGravityTop
вместо обычных перечислений? Как насчет безопасности типов в этом случае? Насколько я понимаю, любой NSString можно передать методу, ожидающему эту константу, без каких-либо предупреждений компилятора.Причины использования констант NSString над перечислениями?
ответ
Я не уверен, но я предполагаю, что это связано с тем, что пользователи добавили свои собственные расширения и подклассы к некоторым материалам Apple. В этом случае вы можете просто переопределить использованный метод и поймать случай, когда строка «MyOwnValue», а затем делать с ней все, что вы хотите. Это значительно проще, чем изменение переименования Apple, и это также мешает вам что-то прикручивать.
Возможно, это также упростит независимость версии от Apple. С перечислениями, если вы каким-то образом измените порядок, это может вызвать множество проблем для любых их значений, которые были кэшированы (по какой-либо причине). Если значение enum равно 1 < < 3, когда оно сохраняется в файле, тогда Apple добавляет еще одно перечисление, так что его значение теперь 1 < < 4, то очевидно, что неправильная вещь выходит из вашей программы. Почему бы им не быть осторожными при перемещении значений enum, я не знаю, но я думаю, что вполне вероятно, что они использовали NSString, потому что нет никакой возможности изменить его значение или порядок в любой версии.
Я подозреваю, что причина историческая или стилистическая больше всего на свете. Вот как это сделали структуры NeXT, и это создало «стиль» какао. Как преимущество этого подхода, проверка значения в отладчике может дать значимое значение (например, @ «CAGravityTop» или что-то вроде этого вместо бессмысленного int
). Поскольку статические строки обрабатываются компилятором разумно, сравнение может быть связано с сопоставлением указателей, а не с равенством строк (см. Ответ bbum), поэтому для этого подхода наблюдается незначительная производительность.
Перечисленные типы не могут быть расширены без добавления дополнительных записей в самом перечисляемом типе. Таким образом, невозможно иметь содержимое перечисления, которое обрабатывается как формальный член перечисляемого типа, но также не отображается во время обычной компиляции.
Возьмите CoreAnimation, например. Могут существовать значения, которые используются внутри, которые не поддерживаются или не доступны через публичный API по целому ряду причин; «информация о реализации» сразу приходит на ум.
Кроме того, строки как константы допускают расширение, как подразумевает Эли. Они также имеют тенденцию быть более информативными при отладке. «kCAGravityTop» является гораздо более показательным, чем, скажем, «4».
С точки зрения производительности, очень мало штрафов за использование строк. Статические строки, из которых внутренняя копия каждой внешней декларации почти каждой строковой константы фактически состоит из, эффективно обрабатываются компилятором, а первый тест метода -isEqualToString: равенство указателя - очень быстро. Не так быстро, как switch(), но при условии величины выполнения кода, подразумеваемой константой, разница в нескольких циклах между switch() и сопоставлением строк не имеет значения.
Еще одна причины, я думал в пользу NSString является то, что он может роздан везде, где id
принимается (например, как userInfo
или как словарные ключей), а примитивные типам (перечисления) будут нужны какое-то обертка для этого
- 1. Статическое использование NSString против встроенных констант NSString
- 2. Причины использования Subversion над MS Source Safe
- 3. итерация над перечислениями в perl
- 4. Причины использования небезопасного кода
- 5. Я работаю над перечислениями, и получаю ошибки
- 6. Как создать статическую NSString [] для статических констант NSString?
- 7. Objective-C: добавление причины NSString к NSException
- 8. Какие у меня причины для использования JRuby над MRI/YARV?
- 9. Любые причины использования JBoss 5 над GlassFish v2/v3 Prelude?
- 10. Любые причины использования JQuery над JS для простых задач?
- 11. Каковы причины использования AJAX над jQuery на стороне клиента?
- 12. Конкретные причины использования | = вместо =
- 13. Причины использования встроенного стиля?
- 14. Любые причины использования даты?
- 15. Практические причины использования procs?
- 16. Причины использования React.cloneElement?
- 17. Причины использования ActionBarSherlock на API11 +
- 18. Правильный способ использования констант Globals
- 19. iphone NSString напрямую использует причины утечки памяти?
- 20. неинициализированное ехЬегп NSString использования
- 21. Построить список переменных констант из других констант
- 22. Причины использования CoreGraphics вместо SpriteKit?
- 23. Причины использования (или нет) stdint
- 24. Причины использования альтернатив lex/yacc?
- 25. Причины отказа от использования IFrame?
- 26. Любые причины для использования CVS?
- 27. Побитовые операции над перечислениями, имеющими более 64 значений
- 28. Побитовые операции над перечислениями Java; RE: Шахматный EG
- 29. WebAPI Modelbinding - [FromUri] не работает над перечислениями гидов
- 30. Причины использования структуры персистентности в Java EE?
+1 Хорошая гипотеза – h4xxr
Кроме того, я считаю, что архивирование и разборки являются фактором.Теперь, когда фреймворки, такие как Core Data, используются гораздо шире, вы обнаруживаете, что, если используются перечисления, существует много бокса и unboxing, которые могут быть просто учтены, если строки используются вместо этого, хотя некоторые соображения все еще остаются для строковых констант - бремя ненужных «сантехника» снижается. – TheBasicMind