1

「seenArray」 #define kseenArray @"seenArray"と「 NSString * const kseenArray = @"seenArray";Why?」にどちらの方法を使用する必要があるかを混乱させました。メモリに関して、もしあれば、どちらが優れているかを知りたいです。

4

4 に答える 4

2

メモリに関しては、コンパイラは文字列リテラルのコピーを作成せず、同じオブジェクトへのすべての参照を作成するため、大きな違いはないと思います。

しかし、私はこれが最善だと思います:

NSString * const kseenArray = @"seenArray";

オブジェクトの内容ではなく ( を使用)、オブジェクトのアドレスに基づいてリテラルを比較できるため、[NSString isEqualToString]より高速です。

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

私はアセンブリについて結論を出すのに十分な知識がないので、テストを作成して結果を提供しました。あなた自身の結論に到達させてください。

私はこの小さなテストを書きました:

#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 に答える