1

我对“seenArray”必须使用哪种方式感到困惑, #define kseenArray @"seenArray"为什么NSString * const kseenArray = @"seenArray";?关于内存,如果有的话,我想知道哪一种更好。

4

4 回答 4

2

就内存而言,我认为它不会有太大的不同,因为编译器不会复制字符串文字,而是会引用同一个对象。

但是我认为这是最好的:

NSString * const kseenArray = @"seenArray";

因为它允许您根据对象的地址而不是其内容(使用[NSString isEqualToString])来比较文字,这样更快:

- (void)someMethod:(NSString *)someString
{
    if (someString == kseenArray)
    {
        ...
    }
}
于 2013-03-19T11:31:21.850 回答
1

由于我对Assembly了解不够,无法下结论,我已经编写了测试并提供了结果,我会让你得出自己的结论

我写了这个小测试:

#import <Foundation/Foundation.h>
NSString * const aString = @"String";
//#define aString @"String"
int main()
{
    NSLog(@"%@", aString);
    return 0;
}

用以下行编译:

gcc StringTest.m -g -m64 -framework Cocoa

这第一个程序集使用#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 

该组件使用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 
于 2013-03-19T11:38:46.560 回答
0

const 字符串更好。

宏保持盲目复制。因此,当您使用宏时,它实际上会创建字符串对象。

但是,放置 const 只会引用全局字符串。

于 2013-03-19T11:28:14.787 回答
0

宏替换发生在编译时。因此,如果您在代码中使用宏 1000x,它与编码相同字符串文字的 1000 个副本相同

使用 const 变量,如果你引用它 1000 次,你仍然引用同一个。

于 2013-03-19T11:30:35.803 回答