The int
type is not object. It is a C language “primitive data type”. You generally interact with primitive C data types directly. E.g.,
int i = 0; // it’s now `0`
i = 42; // it’s now `42`
The NSInteger
is just an alias for another primitive data type, long
. The NSRange
is a struct (thus, also not an object), so the same rule applies. So, for basic interaction with these primitive data types, no *
pointer reference is generally needed. (There actually are times you also deal with pointers to primitive data types, but that is beyond the scope of this question.)
But NSString
, NSNumber
, and NSArray
, however, are objects, so you must use pointers when declaring them.
Note, you've included id
in the latter list where *
is not used:
id firstObject = @"foo";
Be very careful. This actually is a bit misleading, because firstObject
actually is a pointer to the @"someString"
, a NSString
object. The id
is an exception to the way we generally declare pointers with *
and is discussed in Objective-C is a Dynamic Language), “The id
type defines a generic object pointer.”
It’s analogous to declaring a NSString
pointer, but “you lose compile-time information about the object”. Compare the id
pointer to the NSString *
to the following syntax:
NSString *secondObject = @"bar";
This latter secondObject
is NSString *
pointer, but because we explicitly declared it as a NSString *
pointer, the compiler knows that you are dealing with a string (thus the compiler can perform greater validation regarding your subsequent use of that pointer). With id
, you do not enjoy this compile-time validation.
For example, here are two invalid attempts to call removeObject
method on two NSString
objects. NSString
has no such method. The NSString *
reference provides useful compile-time error message that id
does not afford us:
Now, if you used the id
type and tried to run that code, it would crash when it attempted to call removeObject
on firstObject
. But, where possible, it is much better to have the compiler tell us about the error during compile-time, rather than at run-time.
So the id
pattern should be used sparingly, only when you really need Objective-C’s dynamic type behaviors.