Reputation: 5060
I have confused which way I have to use for "seenArray"
#define kseenArray @"seenArray"
and NSString * const kseenArray = @"seenArray";
Why?.In respect to memory ,if any, I want to know about it which one is better.
Upvotes: 1
Views: 300
Reputation: 32066
Since I don't know enough about Assembly to make a conclusion, I've written the test and provided the results, I'll let you reach your own conclusion
I wrote this little test:
#import <Foundation/Foundation.h>
NSString * const aString = @"String";
//#define aString @"String"
int main()
{
NSLog(@"%@", aString);
return 0;
}
compiled with the line:
gcc StringTest.m -g -m64 -framework Cocoa
This first assembly uses #define
0x0000000100000ee0 <main+0>: push %rbp
0x0000000100000ee1 <main+1>: mov %rsp,%rbp
0x0000000100000ee4 <main+4>: sub $0x10,%rsp
0x0000000100000ee8 <main+8>: lea 0x191(%rip),%rax # 0x100001080
0x0000000100000eef <main+15>: lea 0x16a(%rip),%rcx # 0x100001060
0x0000000100000ef6 <main+22>: xor %dl,%dl
0x0000000100000ef8 <main+24>: mov %rax,%rdi
0x0000000100000efb <main+27>: mov %rcx,%rsi
0x0000000100000efe <main+30>: mov %dl,%al
0x0000000100000f00 <main+32>: callq 0x100000f22 <dyld_stub_NSLog>
0x0000000100000f05 <main+37>: movl $0x0,-0x8(%rbp)
0x0000000100000f0c <main+44>: mov -0x8(%rbp),%eax
0x0000000100000f0f <main+47>: mov %eax,-0x4(%rbp)
0x0000000100000f12 <main+50>: mov -0x4(%rbp),%eax
0x0000000100000f15 <main+53>: add $0x10,%rsp
0x0000000100000f19 <main+57>: pop %rbp
0x0000000100000f1a <main+58>: retq
This assembly uses NSString * const
0x0000000100000ee0 <main+0>: push %rbp
0x0000000100000ee1 <main+1>: mov %rsp,%rbp
0x0000000100000ee4 <main+4>: sub $0x10,%rsp
0x0000000100000ee8 <main+8>: mov 0x171(%rip),%rax # 0x100001060 <aString>
0x0000000100000eef <main+15>: lea 0x192(%rip),%rcx # 0x100001088
0x0000000100000ef6 <main+22>: xor %dl,%dl
0x0000000100000ef8 <main+24>: mov %rcx,%rdi
0x0000000100000efb <main+27>: mov %rax,%rsi
0x0000000100000efe <main+30>: mov %dl,%al
0x0000000100000f00 <main+32>: callq 0x100000f22 <dyld_stub_NSLog>
0x0000000100000f05 <main+37>: movl $0x0,-0x8(%rbp)
0x0000000100000f0c <main+44>: mov -0x8(%rbp),%eax
0x0000000100000f0f <main+47>: mov %eax,-0x4(%rbp)
0x0000000100000f12 <main+50>: mov -0x4(%rbp),%eax
0x0000000100000f15 <main+53>: add $0x10,%rsp
0x0000000100000f19 <main+57>: pop %rbp
0x0000000100000f1a <main+58>: retq
Upvotes: 1
Reputation: 122391
In terms of memory I don't think it will make much difference as the compiler won't make a copy of the string literal, and will make all references to the same object.
However I think this is best:
NSString * const kseenArray = @"seenArray";
As it allows you do to compare the literal based on the address of the object, rather than its content (using [NSString isEqualToString]
), which is faster:
- (void)someMethod:(NSString *)someString
{
if (someString == kseenArray)
{
...
}
}
Upvotes: 2
Reputation: 41133
Macro substitution happens on compile time. Hence if you use the macro 1000x in your code, it's the same as coding 1000 copy of the same string literal
With const variable, if you reference it 1000 times, you are still referencing the same one.
Upvotes: 0
Reputation: 17186
const string is better.
Macro keeps copy blindly. So it actually creates the string object when you are using the macro.
However putting const will only refer to the global string.
Upvotes: 0