My project contains more that 5000 constants over the classes, and I want to reduce the memory for those constants. Which is the best way to use to define the constants in Objective-C?
#define
or
My project contains more that 5000 constants over the classes, and I want to reduce the memory for those constants. Which is the best way to use to define the constants in Objective-C?
or
I think the best method to solve your task is using the #define directive. The define directive doesn't use memory at runtime. This directive is executed by a compiler.
Example:
#define MY_CONSTANT @"Hi"
Using in code:
NSString* string = [MY_CONSTANT stringByAppendingString:@" Mac"];
Here you can read about memory allocation for const variables.
Just expanding one of my comments above. The question is
#define MYSTRING @"This is a string"
versus say
NSString *const myString = @"This is a string";
The actual outcome is tool specific. However, examining a binary generated from Xcode, one will find the following:
As expected, both strings must be encoded in the binary, in this case, they will be the __TEXT __cstring
as can be verified by running otool -v -s __TEXT __cstring BINARYNAME
Contents of (__TEXT,__cstring) section
0000000100002f19 This is a string
Keep in mind that this technically consumes memory, as the __TEXT
is very much loaded into memory during runtime. The larger question, which is related to what the OP was asking is along the lines of "what additional memory outside of __TEXT
is incurred by using const
".
Remember that the linker will optimize multiple instances of a string. In other words:
NSString *const string1 = @"I'm a string";
NSString *const string2 = @"I'm a string";
will only result in one instance of that string in __cstring
in the final binary.
So the overhead of using NSString *
seems to be at least a pointer reference. This will be placed either in the __DATA __data
or __DATA __const
section depending on how it is defined:
NSString *const myString = @"This is a string";
Which would yield:
0000000100003068 (__DATA,__const) non-external (was a private external) _myString
NSString *myString = @"This is a string";
Which would yield:
0000000100003d60 (__DATA,__data) non-external (was a private external) _myString
Note that NSString *const
is the way you should be defining it.
So assuming a 64-bit target, your 5,000 string overhead as a const would at least be 40,000 bytes or ~39K. I say at least in case there is some other hidden thing that is being done. But in general, I would expect the pointer to just point to the string in memory.
For most apps, this is probably not very large in the scope of things. So the question one should be asking is what advantages are there for using const
?
And for that aspect, I'll save typing and refer you to the following links. It is preferred to use const
as the compiler can type check.
It actually depends on the case-by-case situation. For your case, I think #define seems to be a better option.
As far as I know:
For #define → No memory access. As token_string will be substituted for each occurrence of identifier, the executable file size increases (storage of literal).
For const → memory will be hit for every access of the variable, and executable file size increases (storage of the variable and storage of a literal which is pointed or referred by the variable).
For a better understanding, please visit "static const" vs "#define" vs "enum" and static const vs #define