1

I have an array with two elements which are 50 and 60:

NSArray*array = [NSArray arrayWithObjects:
                [NSNumber numberWithLong:50],
                [NSNumber numberWithLong:60], nil];

when using the array later on (in fact I´m writing this array as a default list to a plist file) I do it this way:

long value = [array objectAtIndex:1];

After this value contains 15559 what I don´t understand. In the debugger [array objectAtIndex:1] clearly shows (long)60.

enter image description here

I´m sorry, I don´t see what´s wrong ;(

Any ideas?

Ronald

3
  • Using modern Objective-C you can create the array like this: NSArray *array = @[ @50, @60 ];. That's so much easier. Commented Nov 25, 2012 at 5:50
  • And you can get the value like this: long value = [array[1] longValue]; Commented Nov 25, 2012 at 5:51
  • Just to clarify, neither of rmaddy's bits of trivia make any difference to the situation at hand. They're purely stylistic features. Commented Nov 25, 2012 at 8:40

2 Answers 2

6

A long is not an NSNumber. If you want to set value as a long to [array objectAtIndex:1] you must convert it from an NSNumber to a long. You may wish to call longValue on the NSNumber to do that.

You may be wondering why the compiler doesn't complain and help you here. It's probably because an object in an array is fetched as an id, and so most bets are off. This is a common problem with arrays: knowing what you're fetching, and what to do with it, is up to you.

Your screen shot of the debugger is excellent. Notice that if you look at it carefully now, with your head clear, it is very clear about the difference between value which is a long, on the one hand, and array[0] which is an NSNumber wrapping a long, on the other. So the debugger was in fact answering your questions all along!

Sign up to request clarification or add additional context in comments.

4 Comments

Furthermore, 15559 is 0x3cc7 — the address of the NSNumber in slot 1. In 64bit OS X, small numbers are actually stored directly in the pointer with some other information, hence why the difference between 50 and 60 is 0xa00 (ie, 10 * 256), but that's neither here nor there. You wouldn't see the same thing under iOS, for example, or under 32-bit OS X if you were to find a suitably old machine.
I was pretty sure that I had to do some casting. Thanks for the help.
It's not a cast. It's about wrapping and unwrapping. There is a long inside the NSNumber. You put it in there with numberWithLong, so you have to take it back out with longValue.
Just wanted to expand on my previous comment. A cast is the same value treated as a specific type (if you cast explicitly, you are the one specifying what type to treat this value as). This has nothing to do with that; the NSNumber and the long that's inside it are two different values.
2

This is because you are not calling longValue on the object that you get from the array:

long value = [[array objectAtIndex:1] longValue];

What your code gets is an address of NSValue, which gets converted to a "junk" long value unrelated to the number that you stored in the array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.