статическое использование NSString по сравнению со встроенными константами NSString

В Objective C мое понимание - то, что директива "нечто" определяет постоянный NSString. Если я использую "нечто" в нескольких местах, на тот же неизменный объект NSString ссылаются.

Почему делают я вижу этот фрагмент кода так часто (например, в повторном использовании UITableViewCell):

static NSString *CellId = @"CellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellId];

Вместо просто:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId"];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"CellId"];

Я предполагаю, что это должно защитить меня от создания опечатки на имя идентификатора, которое не поймал бы компилятор. Но Если так, не мог я просто:

#define kCellId @"CellId"

и избегайте статического NSString * бит? Или я пропускаю что-то?

42
задан Rajesh 13 August 2014 в 05:32
поделиться

4 ответа

Хорошая практика - превращать буквы в константы, потому что:

  1. Помогает избежать опечаток, как вы сказали
  2. Если вы хотите изменить константу, вам нужно изменить ее только в одном месте

Я предпочитаю использовать статический const NSString* статический NSString* const, потому что это немного безопаснее, чем #define. Я стараюсь избегать препроцессора, если он мне действительно не нужен

.
59
ответ дан 26 November 2019 в 23:27
поделиться

Вы должны сделать статическую переменную const .

Одно различие между статической переменной и макросом заключается в том, что макросы плохо работают с отладчиками. Макросы также небезопасны по типу.

Большая часть рекомендаций static-var-vs-macro для C и C ++ применима к Obj-C.

9
ответ дан 26 November 2019 в 23:27
поделиться

Я предполагаю, что это должно защитить меня от опечатки в имени идентификатора, которую компилятор не обнаружит.

Верно. Это просто базовая практика защитного программирования. Скомпилированный результат (надеюсь) в любом случае будет таким же.

Но если так, не мог бы я просто:

 #define kCellId @ "CellId"

и избежать статического бита NSString *? Или я что-то упустил?

Да. Но символ kCellId будет определяться глобально, по крайней мере, в вашем модуле компиляции. Объявление статической переменной делает символ локальным для этого блока.

Обычно строковые константы определены как глобальные или статические переменные, а не как определения препроцессора. Это помогает гарантировать, что вы имеете дело только с одним экземпляром строки между разными модулями компиляции.

2
ответ дан 26 November 2019 в 23:27
поделиться

Не гарантируется, что при использовании @"foo" в нескольких местах для них используется одно и то же хранилище, и уж точно не гарантируется, что это происходит за пределами модуля компиляции или библиотеки.
. Я бы предпочел использовать статический NSString *string = @"foo", особенно с большим количеством литературных строк.

3
ответ дан 26 November 2019 в 23:27
поделиться