Я разрабатываю приложение Какао , и я использую константы NSString
s как способы хранения имен ключей для моих предпочтений.
Я понимаю, что это хорошая идея, потому что она позволяет легко менять ключи при необходимости.
Плюс, это целое понятие «отделить ваши данные от вашей логики».
В любом случае, есть ли хороший способ сделать эти константы определенными один раз для всего приложения?
Я уверен, что есть простой и умный способ, но сейчас мои уроки просто переопределяют те, которые они используют.
Ответы:
Вы должны создать заголовочный файл как
(вы можете использовать
extern
вместо,FOUNDATION_EXPORT
если ваш код не будет использоваться в смешанных средах C / C ++ или на других платформах)Вы можете включить этот файл в каждый файл, который использует константы или в предварительно скомпилированный заголовок для проекта.
Вы определяете эти константы в файле .m как
Constants.m должен быть добавлен к цели вашего приложения / фреймворка, чтобы он был связан с конечным продуктом.
Преимущество использования строковых констант вместо
#define
d-констант состоит в том, что вы можете проверить на равенство, используя сравнение указателей (stringInstance == MyFirstConstant
), которое намного быстрее, чем сравнение строк ([stringInstance isEqualToString:MyFirstConstant]
) (и легче для чтения, IMO).источник
NSString
свойстваcopy
вместоretain
. Как таковые, они могут (и должны) содержать другой экземпляр вашейNSString*
константы, и прямое сравнение адресов памяти будет неудачным. Кроме того, я бы предположил, что любая разумно оптимальная реализация-isEqualToString:
проверяет равенство указателей, прежде чем приступить к сравнительному анализу символов.Самый простой способ:
Лучший путь:
Одним из преимуществ второго является то, что изменение значения константы не приводит к перестройке всей вашей программы.
источник
extern NSString const * const MyConstant
, т. Е. Сделать ее постоянным указателем на постоянный объект, а не просто постоянным указателем?Есть также одна вещь, чтобы упомянуть. Если вам нужна не глобальная константа, вы должны использовать
static
ключевое слово.пример
Из-за
static
ключевого слова этот констант не виден вне файла.Незначительная коррекция @QuinnTaylor : статические переменные видны в модуле компиляции . Обычно это один файл .m (как в этом примере), но он может укусить вас, если вы объявите его в заголовке, который включен в другом месте, так как вы получите ошибки компоновщика после компиляции
источник
В принятом (и правильном) ответе говорится, что «вы можете включить этот файл [Constants.h] ... в предварительно скомпилированный заголовок проекта».
Как новичок, мне было трудно сделать это без дальнейшего объяснения - вот как: в вашем файле YourAppNameHere-Prefix.pch (это имя по умолчанию для предварительно скомпилированного заголовка в XCode), импортируйте ваш Constants.h внутри
#ifdef __OBJC__
блока .Также обратите внимание, что файлы Constants.h и Constants.m не должны содержать в себе абсолютно ничего, кроме того, что описано в принятом ответе. (Нет интерфейса или реализации).
источник
Я обычно использую способ Барри Уорка и Рахула Гупты.
Хотя я не люблю повторять одни и те же слова в файлах .h и .m. Обратите внимание, что в следующем примере строка практически идентична в обоих файлах:
Поэтому мне нравится использовать некоторые препроцессорные механизмы на языке C. Позвольте мне объяснить на примере.
У меня есть заголовочный файл, который определяет макрос
STR_CONST(name, value)
:В моей паре .h / .m, где я хочу определить константу, я делаю следующее:
et вуаля, у меня есть вся информация о константах только в .h файле.
источник
У меня сам есть заголовок, предназначенный для объявления констант NSStrings, используемых для таких настроек:
Затем объявите их в сопроводительном файле .m:
Этот подход хорошо послужил мне.
Изменить: Обратите внимание, что это работает лучше всего, если строки используются в нескольких файлах. Если его использует только один файл, вы можете просто сделать это
#define kNSStringConstant @"Constant NSString"
в файле .m, который использует строку.источник
Небольшая модификация предложения @Krizz, чтобы он работал должным образом, если заголовочный файл констант должен быть включен в PCH, что довольно нормально. Так как оригинал импортируется в PCH, он не будет перезагружать его в
.m
файл, и поэтому вы не получите никаких символов, а компоновщик недоволен.Однако следующая модификация позволяет ему работать. Это немного запутанно, но это работает.
Вам понадобятся 3 файла,
.h
файл с постоянными определениями,.h
файл и.m
файл, которые я буду использоватьConstantList.h
,Constants.h
иConstants.m
, соответственно. содержаниеConstants.h
просто:и
Constants.m
файл выглядит так:Наконец, в
ConstantList.h
файле есть реальные объявления, и это все:Несколько вещей, чтобы отметить:
Мне пришлось переопределить макрос в
.m
файле после#undef
его использования для макроса, который будет использоваться.Мне также пришлось использовать
#include
вместо#import
этого, чтобы это работало должным образом и чтобы компилятор не видел ранее скомпилированные значения.Это потребует перекомпиляции вашего PCH (и, вероятно, всего проекта) всякий раз, когда какие-либо значения будут изменены, что не имеет место, если они разделены (и дублированы) как обычно.
Надеюсь, что это полезно для кого-то.
источник
extern
вышеуказанное наFOUNDATION_EXPORT
.источник
Как сказал Abizer, вы можете поместить его в файл PCH. Другой способ, который не так грязен, - сделать включаемый файл для всех ваших ключей, а затем либо включить его в файл, в котором вы используете ключи, либо включить его в PCH. Имея их в отдельном включаемом файле, вы, по крайней мере, получаете одно место для поиска и определения всех этих констант.
источник
Если вы хотите что-то вроде глобальных констант; быстрый грязный способ - поместить объявления констант в
pch
файл.источник
Попробуйте использовать метод класса:
Я использую это иногда.
источник
isEqualToString:
для сравнения, которое дальнейшая стоимость во время выполнения. Когда вы хотите константы, делайте константы.Если вам нравится константа пространства имен, вы можете использовать struct, Friday Q & A 2011-08-19: Константы и функции пространства имен
источник
__unsafe_unretained
квалификатором, чтобы он работал.Я использую одноэлементный класс, так что я могу издеваться над классом и изменять константы, если это необходимо для тестирования. Класс констант выглядит так:
И он используется следующим образом (обратите внимание на использование сокращения для констант c - он сохраняет
[[Constants alloc] init]
каждый раз при наборе ):источник
Если вы хотите вызвать что-то подобное
NSString.newLine;
из цели c и хотите, чтобы это было статической константой, вы можете создать что-то вроде этого в swift:И у вас есть хорошее читаемое определение константы, которое доступно из любого типа по вашему выбору, в то время как стиль ограничен контекстом типа.
источник