Причины использовать константы NSString над перечислениями? - PullRequest
7 голосов
/ 20 августа 2009

Мне интересно, почему Apple использует (довольно интенсивно в CoreAnimation, но и в других местах) константы, которые объявлены как NSString * const, например, kCAGravityTop, вместо обычных перечислений? Как насчет безопасности типов в этом случае? Насколько я понимаю, любой метод NSString можно передать методу, ожидающему эту константу, без получения предупреждений компилятора.

Ответы [ 4 ]

11 голосов
/ 20 августа 2009

Я не уверен, но я предполагаю, что это связано с тем, что пользователи добавляют свои собственные расширения и подклассы к некоторым вещам Apple. В этом случае вы можете просто переопределить используемый метод и поймать случай, когда строка является «MyOwnValue», а затем делать с ней все, что вы хотите. Это значительно проще, чем модифицировать перечисление Apple, и не дает вам ничего испортить.

Кроме того, Apple может облегчить независимость от версии. С перечислениями, если вы каким-то образом измените их порядок, это может вызвать много проблем для любого из их значений, которые были кэшированы (по любой причине). Если значение enum равно 1 << 3, когда оно сохраняется в файл, то Apple добавляет другое перечисление, так что его значение теперь равно 1 << 4, тогда, очевидно, из вашей программы выходит не то, что нужно. Почему бы им просто не позаботиться о перемещении значений перечисления, я не знаю, но я думаю, что вполне вероятно, что они использовали NSString, потому что нет способа изменить его значение или порядок в любой версии.

9 голосов
/ 20 августа 2009

Перечисляемые типы не могут быть расширены без добавления дополнительных записей в самом перечисляемом типе. Таким образом, невозможно иметь содержимое перечисления, которые оба обрабатываются как формальный член перечисляемого типа, но также не видны при обычной компиляции.

Взять, к примеру, CoreAnimation. Могут быть значения, которые используются внутри компании, которые не поддерживаются или не доступны через открытый API по ряду причин; сразу приходит на ум "деталь реализации".

Кроме того, строки как константы позволяют расширение, как подразумевает Eli. Они также имеют тенденцию быть намного более информативными при отладке. «kCAGravityTop» гораздо более показателен, чем, скажем, «4».

С точки зрения производительности очень мало штрафов за использование строк. Статические строки, из которых фактически состоит внутренняя копия каждого внешнего объявления почти каждой строковой константы, эффективно обрабатываются компилятором, и первый тест -isEqualToString: метода - это равенство указателей - очень быстро. Не так быстро, как switch (), но, учитывая величину выполнения кода, подразумеваемую константой, разница в несколько циклов между switch () и сравнением строк не имеет значения.

7 голосов
/ 20 августа 2009

Я подозреваю, что причина историческая или стилистическая больше, чем что-либо еще. Вот как это сделали фреймворки NeXT, и это создало «стиль» Какао. В качестве преимущества этого подхода проверка значения в отладчике может дать значимое значение (например, @ "CAGravityTop" или что-то подобное вместо бессмысленного int). Так как статические строки обрабатываются компилятором разумно, сравнение может быть сравнением указателя, а не равенством строк (см. Ответ bbum), поэтому при таком подходе незначительное снижение производительности.

5 голосов
/ 20 августа 2009

Еще одна причина, по которой я думал в пользу NSString, заключается в том, что он может передаваться везде, где принимается id (например, userInfo или в качестве ключей словаря), в то время как примитивным типам (перечислениям) для этого потребуется какая-то оболочка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...