Sanoj Kashyap
Sanoj Kashyap

Reputation: 5060

which one is better Macro or String Constants?

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

Answers (4)

James Webster
James Webster

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

trojanfoe
trojanfoe

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

gerrytan
gerrytan

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

Apurv
Apurv

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

Related Questions