Why don't I declare NSInteger with a *

33,169

Solution 1

NSInteger is a primitive type, which means it can be stored locally on the stack. You don't need to use a pointer to access it, but you can if you want to. The line:

NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

returns an actual variable, not its address. To fix this, you need to remove the *:

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

You can have a pointer to an NSInteger if you really want one:

NSInteger *pointerToProcessID = &processID;

The ampersand is the address of operator. It sets the pointer to the NSInteger equal to the address of the variable in memory, rather than to the integer in the variable.

Solution 2

The reason that you don't declare NSInteger with a * is because it isn't an object. An NSInteger is simply an int or a long:

#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif

If it's being used in a 32-bit application, it's a 32-bit integer, and if it's being built in a 64-bit application, it's a 64-bit integer.

Of course, you can pass an NSInteger as a pointer, but most functions simply take arguments as an NSInteger and not a pointer to it.

Objects, on the other hand, can only be passed to other functions as pointers. This is because objects have memory dynamically allocated for them, and so cannot be declared on the stack. Since an int or long has a fixed amount of memory allocated for them, this is not an issue.

Solution 3

The * means “pointer”. The object variable holds a pointer to an object, so it has a *; the NSInteger variable holds an NSInteger, not a pointer to an NSInteger, so it does not have a *. Putting the * on that variable gives you at least a warning because you're putting an integer into a pointer variable.

Solution 4

NSInteger is just a typedef for int, AFAIK.

Share:
33,169
gargantuan
Author by

gargantuan

Designer developer, living and working in London UK.

Updated on July 09, 2022

Comments

  • gargantuan
    gargantuan almost 2 years

    I'm trying my hand at the iPhone course from Stanford on iTunes U and I'm a bit confused about pointers. In the first assignment, I tried doing something like this

    NSString *processName = [[NSProcessInfo processInfo] processName];
    NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
    

    Which generated an error, after tinkeing around blindly, I discovered that it was the * in the NSInteger line that was causing the problem.

    So I obviously don't understand what's happening. I'll explain how I think it works and perhaps someone would be kind enough to point out the flaw.

    Unlike in web development, I now need to worry about memory, well, more so than in web development. So when I create a variable, it gets allocated a bit of memory somewhere (RAM I assume). Instead of passing the variable around, I pass a pointer to that bit of memory around. And pointers are declared by prefixing the variable name with *.

    Assuming I'm right, what puzzles me is why don't I need to do that for NSInteger?

  • gargantuan
    gargantuan almost 15 years
    I suspect that's going to be a very handy tip. Thanks.
  • KRISH SHAH
    KRISH SHAH almost 15 years
    That was a major gotcha for me when I moved from webdev to iPhone development. The other one to watch out for is making sure to terminate NSArray's with nil.
  • Mike Weller
    Mike Weller almost 15 years
    If you Apple-double-click on NSInteger or other types you are confused about in XCode, you can get taken to its definition, which in this case will be: typedef int NSInteger; So it's a plain old int after all.
  • Chuck
    Chuck almost 15 years
    That isn't valid. The & operator requires an lvalue, while the method call is an rvalue.
  • Nico
    Nico over 13 years
    It can be, but isn't everywhere. On 64-bit Mac OS X systems, NSInteger is defined as long. It's not hard to imagine that this might be true on an architecture running iOS someday.
  • erikprice
    erikprice almost 13 years
    Also note that this example is only useful if you are going to use the processID pointer within the same call stack. If you need to use it later, you'd need to allocate memory on the heap using calloc and then store the value into that memory. Something like this: NSInteger *processID = calloc(1, sizeof(NSInteger)); *processID = [[NSProcessInfo processInfo] processIdentifier];
  • Roman
    Roman about 10 years
    Still don't understand why it's not better to store pointer to NSInteger. Does NSInteger takes less memory than pointer - so it's more efficient to pass NSInteger than pointer?