Objective-C статические, внешние, открытые переменные
Я хочу иметь переменную, к которой я могу получить доступ в любом месте, импортируя файл заголовка, но я также хочу, чтобы он был статическим в том смысле, что существует только один из них. В моем.файл м, указать
static BOOL LogStuff = NO;
и в методе initialize я устанавливаю значение ведения журнала:
+ (void)initialize
{
LogStuff = ... //whatever
}
однако я хочу иметь доступ к моей переменной в любом месте, импортируя .H-файл, поэтому я хочу сделать что-то вроде этого:
static extern BOOL LogStuff;
но мне не разрешено это делать. Это возможно ли сделать то, что я пытаюсь сделать? Спасибо
5 ответов
static
в Objective-C означает другое, чем static
в классе C++, в контексте членов данных статического класса и методов статического класса. В C и Objective-C, a static
переменная или функция в глобальной области означает, что этот символ имеет внутренняя перелинковка.
внутренняя связь означает, что этот символ является локальным для текущего ЕП, который является текущим исходным файлом (.c
или .m
) компилируется и все заголовочные файлы, которые он рекурсивно включает. На этот символ нельзя ссылаться из другой единицы перевода, и вы можете иметь другие символы с внутренней связью в других единицах перевода с тем же именем.
Итак, если у вас есть заголовочный файл, объявляющий переменную как static
, каждый исходный файл, который включает в себя заголовок, получает отдельные глобальная переменная - все ссылки на эту переменную в одном исходном файле будут ссылаться на ту же переменную, но ссылки в различные исходные файлы будут ссылаться на разные переменные.
если вы хотите иметь одну глобальную переменную, вы не можете иметь ее в области классов, как в C++. Один из вариантов-создать глобальную переменную с внешняя связь: объявите переменную с помощью extern
ключевое слово в заголовочном файле, а затем в один исходный файл, определите его в глобальной области видимости без extern
ключевое слово. Внутренняя связь и внешняя связь взаимны exclusive-у вас не может быть переменной, объявленной как both extern
и static
.
альтернативы, как Панос предложил, было бы использовать метод класса вместо переменной. Это сохраняет функциональность в пределах класса, что имеет больше смысла семантически, и вы также можете сделать это @private
если вы так хотите. Он добавляет предельной производительности, но это вряд ли будет узким местом в вашем приложении (если вы подозреваете это, всегда профиль первый).
Если LogStuff
является статическим полем класса, возможно, вы можете реализовать статический геттер и сеттер?
+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;
объявить его extern BOOL
в файле header. Файлы #import
ваш заголовок не знает или не заботится, является ли внешний символ статическим или нет.
отдельная глобальная переменная (по одной на исходный файл):
// .h
static NSString * aStatic;
//.m
static NSString * aStatic = @"separate";
уникальная глобальная переменная:
// .h
extern NSString * anExtern;
// .m
NSString * anExtern = @"global";
Я обычно использую этот макет для моего статика:
NSMutableArray *macroArray;
BOOL keepMacro;
+ (void) startMacro
{
if (macroArray == nil)
{
macroArray = [[NSMutableArray alloc] initWithCapacity:100];
}
[macroArray removeAllObjects];
keepMacro = YES;
}
это в моем приложении. Оба Bool
и macroArray
являются статическими, но обратите внимание, что они не объявлены static
или extern
.
это может быть не лучшая практика, но это то, что я делаю.