简体   繁体   中英

Global constants in Objective-C

I've a file called Constants.h :

extern NSString * const BASE_URL;

and Constants.m :

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

First question: How can I switch DEBUG to be True and False ?


I've a view controller file 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

[...]

The code doesn't work and returns me this error:

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

How can I fix this?

I need to combine several global string variabile with other strings for create various urls.


UPDATE 1

Now Constants.m is:

#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/");

But there is an error on the last line Parse error: expected ')' . Probably I can use CFSTR only with macros. I need to find a way for have all my global variables.

Solution A:

Personally, I would just use a function for ANOTHER_URL .

Solution B:

If you really want a constant: You should be able to use cstring concatenation rules via #define , then pipe that through 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/");

Solution C:

If you want to create just one via initialization, you can also accomplish a function/method local static in C++/ObjC++ translations (then use C or ObjC visibility, where needed):

NSString * URL() {
  static NSString * const ANOTHER_URL = [NSString stringWithFormat:@"%@%@", BASE_URL, @"/path/"];
  return ANOTHER_URL;
}

Firstly, you can tell Xcode to set some preprocessor macros for debug builds. Use the build option 'preprocessor macros'.

For your second question, you can't call an objective-C method to fill a constant, because that stuff isn't available at compile-time. Your best option is to define the global variable, then give it a value in the class 'initialize' method.

static NSString * ANOTHER_URL;

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

initialize is called before your first instance of the class is created, so it's safe. You'll have to drop the const keyword, but I'm sure you can trust yourself! ;)

#define DEBUG 1 or 0 to disable.

The error is because you are calling a method of NSString while its a compile constant. In other words you are telling the compiler something it simply can't handle. You will need to initialize such a dynamic link on launch, the compiler can't do this for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM