Эквивалент открытых статических конечных переменных
Я понимаю, что размещение слова extern
Перед объявлением переменной в заголовочном файле объявляет о существовании глобальной статической переменной без ее инициализации. Я также понимаю, что если я импортирую файл, содержащий переменные extern
, я могу ссылаться на них без имени класса / файла. Но как определить их и их ценности?
То, что я пытаюсь сделать, - это создать класс констант с глобальными константами, которые я хочу использовать в приложении iOS. код.
Можно ли поместить их в интерфейс вот так?
Пример.h
#import <Foundation/Foundation.h>
@interface Constraints : NSObject
{
extern NSString * const PREFS_NAME;
}
Или кто-то ставит тогда вне интерфейса, как это
Пример.h
#import <Foundation/Foundation.h>
extern NSString * const PREFS_NAME;
@interface Constraints : NSObject
{
}
Затем в реализации .m file как инициализировать значения extern?
Внутри такой области реализации?
Пример.m
#import "Constraints.h"
@implementation Constraints
/**PRefecences name for the application**/
const NSString * PREFS_NAME = @"MyApp_Prefs";
@end
Или инициализировать их вне области реализации, как это:
Пример.m
#import "Constraints.h"
/**PRefecences name for the application**/
const NSString * PREFS_NAME = @"MyApp_Prefs";
@implementation Constraints
@end
Или я предоставляю им их начальные значения в конструкторе? или какой-то произвольный метод статического стиля с +
перед ним, т. е. +(void) setAppConstraints
;
public static final
в Java.
Также каковы пределы команды extern
? Я знаю, что могу extern
an NSInteger
или NSString
, но как насчет NSArray
?
extern
в Objective-C. Многие ответы кажутся спекулятивными. Я надеюсь, что этот вопрос будет хорошим ресурсом не только для меня, но и для ограничения дальнейших подобных вопросов об основах из extern
.2 ответа:
Вы определяете его значение в файле, внутри которого он объявлен, что в вашем случае является примером.m; вы все еще можете повторно назначить эту переменную, поэтому объявление в Примере.h будет выглядеть так:
extern NSString * PREFS_NAME;
Таким образом, каждый файл, который импортирует пример.h имеет доступ к этой переменной. Эквивалент общедоступные статические заключительные в Objective-C является константной. Если вы также хотите, чтобы он был общедоступным, вы должны сделать его переменной экземпляра класса, но в этом случае он вам не нужен, потому что он уже доступен везде. Так что в данном случае это будет:
// .m file NSString* const PREFS_NAME = @"MyApp_Prefs"; // .h file extern NSString* const PREFS_NAME;
Также обратите внимание, что const NSString * отличается от NSString* const. Последний является указателем const на NSString. Первый не имеет смысла, даже если это правильный синтаксис. В Objective-C классификатор const не влияет на объекты, вместо этого существуют изменяемые и неизменяемые классы. Это имело бы смысл в C++, что означает, что вы можете использовать только методы const на экземпляре.
extern
используется для передачи компилятору сигнала о том, что вы будете использовать переменную или функцию, определенную в другом блоке компиляции.Когда вы говорите
extern const NSString *PREFS_NAME
, Вы говорите: "замените все ссылки в этом блоке компиляции на PREFS_NAME на переменную PREFS_NAME, как она определена в другом файле."Поэтому, когда вы пытаетесь назначить PREFS_NAME в вашем .м, все, что вы делаете, это пытаетесь назначить переменную, которая, хотя и имеет имя, не существует. Объявление переменнойextern
является только объявление переменной или функции, а неопределение этой переменной или функции. Это позволяет компилятору знать, что имя используется, и что компоновщик позаботится о том, что с ним делать, но даже если вы предоставляете тип здесь, он на самом деле не выделяет пространство для переменной, он ожидает, что пространство будет выделено в блоке компиляции, который фактически определяет переменную.Вы компилируете три или четыре разных файла исходного кода вместе, три из которых они могут заявить:
extern int buffer[];
И можно объявить
int buffer[BUFSIZE];
В своей глобальной области, и задача компоновщика состоит в том, чтобы разрешить три объявленные ссылки на
extern buffer
к фактическому определению буфера четвертого.
extern
это для переменных и функций C так же, как@class
для классов Objective-C, это прямое объявление, обещание компилятору, что вам не нужно волноваться, когда вы видите имя, которое здесь не определено, потому что компоновщик ответит на все, что угодно возможно, у вас есть какие-то нерешенные вопросы.