#define or const string*

15,290

Solution 1

Looking from the perspective of the compiler, #define is a preprocessor directive (refer to the definition in c, http://en.wikipedia.org/wiki/C_preprocessor).

In this case, compiler might be doing the whole text replacement before compiling your codes.

e.g.: if you define:

#define GET_ENTRY_URL(__MY_ENTRY_ID__) [NSString stringWithFormat:@"http://api.myblog.com/posts/entries/%@", __MY_ENTRY_ID__];

it could be replacing every occurrences of GET_ENTRY_URL(x) with [NSString ..., x] in your codes. Potentially, instances might be created everywhere we use the macro if the implementation of objective-c is following this.

static const/variable seems to be a better way.

Solution 2

What I did in my app was define a const for the base path and a const for each specific path with substitution format codes inside the path when necessary.

NSString const *APIBasePath        = @"http://api.mydomain.com";
NSString const *APIEntryPath       = @"/entries/%d";
NSString const *APIUpdateEntryPath = @"/entries/%d/update";

I then construct the URL at runtime for each API as follows:

- (void)updateEntryNumber:(NSUInteger)entryNumber
{
  NSString *updateEntryPath = [NSString stringWithFormat:APIUpdateEntryPath, entryNumber];
  NSString *APIPath = [APIBasePath stringByAppendingPathComponent:updateEntryPath];
  // do something
}
Share:
15,290
Mugunth
Author by

Mugunth

iOS Developer/Author/Blogger and Usability Guy. http://blog.mugunthkumar.com Co-author of the book iOS Programming: Pushing the Limits I will not answer your question here on Stackoverflow if you ask anything about Iphone or IPHONE or I-phone.

Updated on August 02, 2022

Comments

  • Mugunth
    Mugunth almost 2 years

    I know this question has been asked several times, but mine is slightly different. Before closing this as duplicate, please read it fully. There are many posts on stack overflow that says, "Personally, I hate MACROS, Don't use that shit". I've read all those and my case is different. I'm trying to define URLs used in a software (iOS app) using #define macros.

    I agree that using const strings is a better practice than #define macros. But in an increasingly REST based API world that accepts query parameters as a part of URL, how can you still use const strings to represent a URL that changes?

    Instead of http://api.myblog.com/posts?entryid=%@ a API Server that following REST principles would have http://api.blog.com/posts/entries/[entryid]

    In the former type, URL is http://api.myblog.com/posts for all entries and they don't change. A const string was possible.

    In the latter type, URL changes with every entry and I use a Macro that expands to a full URL like this.

    #define GET_ENTRY_URL(__MY_ENTRY_ID__) [NSString stringWithFormat:@"http://api.myblog.com/posts/entries/%@", __MY_ENTRY_ID__];
    

    Are there any design flaws in my method? Would like to know your inputs.

    Thanks.

  • Mugunth
    Mugunth over 12 years
    How do you pass variables in static const nsstrings?
  • alvinsj
    alvinsj over 12 years
    you know you can't, since it is a constant. imho, if the api gets more complicated, i will construct class like an NSURL , url construction can be done inside. maybe it is not crucial yet to use macro or not, but when this piece of codes gets to many places, things might feel wrong again. e.g.: split all GET_ENTRY_URL(x) into two GET_CODING_ENTRY_URL(x), GET_PERSONAL_ENTRY_URL(x).
  • Kjuly
    Kjuly over 12 years
    I just found that the stringByAppendingPathComponent: returns only one slash, i.e. http:/..., it seems that this method is used for file path, not url. Instead, I use stringByAppendingString:. :)