Question

I've been learning about modern Objective-C recently and started using the wonderful new syntax for NSNumber literals. After reading up there are actually two ways to create NSNumbers:

// NSNumber literal
NSNumber *a = @42;

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

The net result is the same (both generate an NSNumber with a value of 42), but are there any reasons to use the literal over the boxed expression for simple numeric constants?

I can see two style reasons to prefer boxed expressions:

  1. Easier to visually parse, especially if the number is negative or a macro (Xcode syntax highlighting doesn't correctly color @-1 or @INT_MAX).
  2. Easier to change to a non-constant expression later if needed without having to add the parentheses. Similar to the arguments about adding braces to single line if statements for "future proofing".

But are there any negatives or reasons to stick with the literal? The Clang page doesn't mention anything in the boxed expressions section that would indicate a loss of performance or other negative side effects.

So in the case of these simple numeric constants is this just a case of style?

Was it helpful?

Solution

These in fact compile to the same assembly:

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

This leads to the following optimized assembly:

    // 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

It's worth noting that it's even smart enough to do pre-computing for you:

    // 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

So as @Zaph says, it doesn't matter to the compiler.

OTHER TIPS

Since each case actually "boxes" the integer into an object it is an issue of clarity, similar to adding extra "()" for operator precedence when they are not needed.
Ex: 2+3*4 vs: 2+(3*4)

Personally I write @42 not @(42)
but @(kMeaningOfLifeAndEverything) is OK ;-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top