25

Why doesn't this please the compiler? Casting is supposed to work like in C as I can read here How to cast an object in Objective-C.

[p setAge:(NSNumber*)10];

where

- (NSNumber*) age {
    return _age;
}
- (void) setAge: (NSNumber*)input {
    [_age autorelease];
    _age = [input retain];
}
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Rebol Tutorial
  • 2,738
  • 2
  • 25
  • 36

5 Answers5

55

In a sort of symmetry with your earlier question, NSNumber is an object type. You need to create it via a method invocation such as:

[p setAge:[NSNumber numberWithInt:10]];

Your current code is attempting simply to cast the arbitrary integer 10 to a pointer. Never do this: if the compiler didn't warn you about it, you would then be trying to access some completely inappropriate bytes at memory location 10 as if they were an NSNumber object, which they wouldn't be. Doing that stuff leads to tears.

Oh, and just to preempt the next obvious issues, remember that if you want to use the value in an NSNumber object, you need to get at that via method calls too, eg:

if ( [[p age] intValue] < 18 )
    ...

(NSNumber is immutable, and I think it is implemented such that identical values are mapped to the same object. So it is probably possible to get away with direct pointer comparisons for value equality between NSNumber objects. But please don't, because that would be an inappropriate reliance on an implementation detail. Use isEqual instead.)

Community
  • 1
  • 1
walkytalky
  • 9,453
  • 2
  • 36
  • 44
  • Only a subset of possible NSNumber values are cached as singletons, the rest are individual instances. The exact set of what is cached has changed over time (and will likely change in the future). +1 for emphasizing the use of `isEqual:`. – bbum Dec 05 '10 at 19:49
32

Today it is also possible to do it using shorthand notation:

[p setAge:@(10)];
Maxim Chetrusca
  • 3,262
  • 1
  • 32
  • 28
  • 7
    You can also drop the parentheses if you're just using 10. Ie @10. You only need the parentheses if using a variable name or sum etc... – Fogmeister Jun 20 '14 at 18:59
6
NSNumber *yourNumber = [NSNumber numberWithInt:your_int_variable];
Paul Hoffer
  • 12,606
  • 6
  • 28
  • 37
Luda
  • 7,282
  • 12
  • 79
  • 139
6

Use this:

[p setAge:[NSNumber numberWithInt:10]];

You can't cast an integer literal like 10 to a NSNumber* (pointer to NSNumber).

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • thanks can you also tell why since casting is supposed to work like in c as I can read here http://stackoverflow.com/questions/690748/how-to-cast-an-object-in-objective-c – Rebol Tutorial Dec 05 '10 at 13:22
5

Because NSNumber is an object and "10" in a primitive integer type, much like the difference between int and Integer in Java. You, therefore, need to call its initialiser:

[p setAge:[NSNumber numberWithInt:10]
Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152