1

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.

Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75

4 Answers4

2

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)
    {
        ...
    }
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
1

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 
James Webster
  • 31,873
  • 11
  • 70
  • 114
0

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.

Apurv
  • 17,116
  • 8
  • 51
  • 67
0

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.

gerrytan
  • 40,313
  • 9
  • 84
  • 99
  • do you want to say both are same? – Sanoj Kashyap Mar 19 '13 at 11:36
  • Depends on how the compiler treats it. Smart compiler might notice you have 1000 immutable string literals scattered everywhere and optimizes it. With reference to const variable you're more likely to not have duplication – gerrytan Mar 19 '13 at 11:41