我对“seenArray”必须使用哪种方式感到困惑,
#define kseenArray @"seenArray"
为什么NSString * const kseenArray = @"seenArray";
?关于内存,如果有的话,我想知道哪一种更好。
问问题
285 次
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 回答