Глобальные константы в Objective-C - PullRequest
8 голосов
/ 07 ноября 2011

У меня есть файл с именем Constants.h :

extern NSString * const BASE_URL;

и Constants.m :

#ifdef DEBUG
    NSString * const BASE_URL = @"http://www.example.org ";
#else
    NSString * const BASE_URL = @"http://localhost";
#endif

Первый вопрос: Как я могу переключить DEBUG на True и False?


У меня есть файл контроллера представления MyViewController.m:

#import "MyViewController.h"
#import "Constants.h"

// this doesn't works. see above for the error.
static NSString * const ANOTHER_URL = [NSString stringWithFormat:@"%@%@", BASE_URL, @"/path/"];

@implementation HomeViewController

[...]

Код неработать и возвращает мне эту ошибку:

error: Semantic Issue: Initializer element is not a compile-time constant

Как я могу это исправить?

Мне нужно объединить несколько глобальных строковых переменных с другими строками для создания различных URL-адресов.


ОБНОВЛЕНИЕ 1

Сейчас Constants.m равно:

#import "Constants.h"

#ifdef DEBUG
    #define DEF_BASE_URL "http://www.example.org/"
#else
    #define DEF_BASE_URL "http://localhost/"
#endif

NSString * const BASE_URL = (NSString*)CFSTR(DEF_BASE_URL);
NSString * const API_URL = (NSString*)CFSTR(DEF_BASE_URL "api/");
NSString * const API_SETTINGS_URL = (NSString*)CFSTR(API_URL "settings/");

Но в последней строке есть ошибка Ошибка разбора: ожидается ')«.Вероятно, я могу использовать CFSTR только с макросами.Мне нужно найти способ иметь все мои глобальные переменные.

Ответы [ 3 ]

6 голосов
/ 07 ноября 2011

Решение A:

Лично я бы просто использовал функцию для ANOTHER_URL.

Решение B:

Если вам действительно нужна константа: вы должны быть в состоянии использовать правила объединения cstring через #define, а затем передать это через CFSTR():

// defs.h
extern NSString * const BASE_URL;
extern NSString * const ANOTHER_URL;

// defs.m

#ifdef DEBUG
#define DEF_BASE_URL "http://www.example.org"
#else
#define DEF_BASE_URL "http://localhost"
#endif

NSString * const BASE_URL = (NSString*)CFSTR(DEF_BASE_URL);
NSString * const ANOTHER_URL = (NSString*)CFSTR(DEF_BASE_URL "/path/");

Решение C:

Если вы хотите создать только один с помощью инициализации, вы также можете выполнить локальную статическую функцию / метод в переводах C ++ / ObjC ++ (затем используйте видимость C или ObjC, где это необходимо):

NSString * URL() {
  static NSString * const ANOTHER_URL = [NSString stringWithFormat:@"%@%@", BASE_URL, @"/path/"];
  return ANOTHER_URL;
}
1 голос
/ 07 ноября 2011

Во-первых, вы можете указать Xcode установить некоторые макросы препроцессора для отладочных сборок.Используйте параметр сборки 'preprocessor macros'.

Для вашего второго вопроса вы не можете вызвать методjective-C, чтобы заполнить константу, потому что это не доступно во время компиляции.Лучше всего определить глобальную переменную, а затем присвоить ей значение в методе класса initialize.

static NSString * ANOTHER_URL;

+ initialize {
    ANOTHER_URL = [NSString stringWithFormat:@"%@%@", BASE_URL, @"/path/"];
}

initialize вызывается до создания первого экземпляра класса, поэтому это безопасно.Вам придется отбросить ключевое слово const, но я уверен, что вы можете доверять себе!;)

0 голосов
/ 07 ноября 2011

# определить DEBUG 1 или 0 для отключения.

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

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