我最近一直在学习现代Objective-C,并开始使用NSNumber
文字的精彩新语法。阅读后,实际上有两种创建NSNumber
的方法:
// NSNumber literal
NSNumber *a = @42;
// Boxed expression
NSNumber *a = @(42);
最终结果是相同的(两者都生成NSNumber
,值为42),但是对于简单的数字常量,是否有任何理由将文字用于盒装表达式?
我可以看到两种风格理由更喜欢盒装表达式:
@-1
或@INT_MAX
)。但是,是否有任何负面或理由坚持文字? Clang page未在框中的表达式部分中提及表示性能损失或其他负面影响的任何内容。
所以在这些简单的数字常量的情况下,这只是样式的一种情况吗?
答案 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)没问题; - )