20
votes

I love the shorthand handling of string literals in Objective C with the @"string" notation. Is there any way to get similar behavior with NSNumbers? I deal with numbers more and it's so tedious having [NSNumber numberWithWhatever:] calls everywhere. Even creating a macro would work, but my knowledge of how best to do that is limited.

4
As pointed out by rjstelling, this is now a feature in clang. Much rejoicing. Please vote to close, thanks.rob5408
There's no need to close this. It's a perfectly valid question. Closure is for undesirable questions, where answers need to be prevented.jscs
You should accept @rjstelling's answer instead though as it is more correct now.Philippe Sabourin
Hmm, I wonder what the SO perspective on that is. Tilo answered the question as it was at that time so it seems a bit unfair to award it to another person after the facts changed. Like discounting von Neumann because he didn't foresee multi-cores or something. At 1542 views over three years this question isn't exactly even getting used that much. In addition, I think Tilo's answer and JeremyP's improvements could still be useful to someone maybe looking for NSSet literal syntax or NSMutableArray literal syntax workarounds however unlikely they are to show up here looking towards that end.rob5408

4 Answers

32
votes

Since nobody has mentioned this... If you need to wrap a value in an NSNumber, the NSNumber literal syntax is as follows.

int val = 13;
NSNumber *numVal = @(val);
31
votes

As of Clang v3.1 you can now use Objective-C literals.

NSNumber *fortyTwo = @42;             // equivalent to [NSNumber numberWithInt:42]
NSNumber *fortyTwoUnsigned = @42U;    // equivalent to [NSNumber numberWithUnsignedInt:42U]
NSNumber *fortyTwoLong = @42L;        // equivalent to [NSNumber numberWithLong:42L]
NSNumber *fortyTwoLongLong = @42LL;   // equivalent to [NSNumber numberWithLongLong:42LL]

So, answering your specific question:

[Tyler setArms:[[[NSNumber alloc] initWithInt:1] autorelease]];

Can now be written as:

[Tyler setArms:@1];

There are also literals for arrays and dictionaries, but they are beyond the scope of this question.

To take advantage of literals in Xcode you'll need at least version 4.4 -- this comes with Apple's LLVM 4.0 compiler.

9
votes

I'm using a macro like

#define N(x) [NSNumber numberWithInt: x]

wich leads to code like

[N(123) intValue];

update:

One should be aware of the CPU and memory consumption of such a macro. While the @"…" strings are static compiler generated strings of the constant string class (depends on foundation maybe NSConstantString in Cocoa?) the macros create code which is evaluated at runtime and therefore create a new object every time they are called.

7
votes

Xcode 4.4 has introduced the Clang features that rjstelling mentioned for literals for NSNumber, NSArray and NSDictionary. The syntax is simple:

//Number literal
NSNumber *pi = @3.14;

//Array literal
NSArray *primes = @[ @2, @3, @5, @7, @11 ]; //No nil terminator needed

//Dictionary literal
NSDictionary *dict = @{
    @"key1": @42,
    @"key2": @"Another key",
    @3: @"A NSNumber key"
}; //No nil terminator, stored in "key:value," format