有没有使用括号来表示NSNumber文字的原因?

时间:2013-11-18 19:49:56

标签: objective-c objective-c-literals

我最近一直在学习现代Objective-C,并开始使用NSNumber文字的精彩新语法。阅读后,实际上有两种创建NSNumber的方法:

// NSNumber literal
NSNumber *a = @42;

// Boxed expression
NSNumber *a = @(42);    

最终结果是相同的(两者都生成NSNumber,值为42),但是对于简单的数字常量,是否有任何理由将文字用于盒装表达式?

我可以看到两种风格理由更喜欢盒装表达式:

  1. 更容易进行视觉分析,尤其是当数字为负数或宏时(Xcode语法高亮显示不能正确着色@-1@INT_MAX)。
  2. 如果需要,可以在以后更轻松地更改为非常量表达式,而无需添加括号。类似于关于将“大括号”添加到“未来校对”的单行if语句的论点。
  3. 但是,是否有任何负面或理由坚持文字? Clang page未在框中的表达式部分中提及表示性能损失或其他负面影响的任何内容。

    所以在这些简单的数字常量的情况下,这只是样式的一种情况吗?

2 个答案:

答案 0 :(得分:5)

这些实际上编译为同一个程序集:

NSNumber *value = @42;
NSNumber *otherValue = @(42);

这导致以下优化组装:

    // NSNumber *value = @42;

movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%edi), %eax <-- NSNumber
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%edi), %ecx    <-- numberWithInt:
movl    %ecx, 4(%esp)
movl    %eax, (%esp)
movl    $42, 8(%esp)   <-- Here's your value
calll   L_objc_msgSend$stub

    // NSNumber *value = @(42);

movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%edi), %eax <-- NSNumber
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%edi), %ecx    <-- numberWithInt:
movl    %ecx, 4(%esp)
movl    %eax, (%esp)
movl    $42, 8(%esp)  <--- and here again
calll   L_objc_msgSend$stub

值得注意的是,为你做预先计算甚至足够聪明:

    // NSNumber *value = @(42 + 1);

movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%edi), %eax <-- NSNumber
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%edi), %ecx    <-- numberWithInt:
movl    %ecx, 4(%esp)
movl    %eax, (%esp)
movl    $43, 8(%esp)  <--- Hey; it's precomputed to 43. Nice.
calll   L_objc_msgSend$stub

正如@Zaph所说,这与编译器无关。

答案 1 :(得分:2)

由于每个案例实际上将整数“包装”到一个对象中,这是一个清晰的问题,类似于在不需要时为运算符优先级添加额外的“()”。
例如:2 + 3 * 4 vs:2+(3 * 4)

我个人写@ 42而不是@(42)
但@(kMeaningOfLifeAndEverything)没问题; - )