DISCLAIMER
The discussion below gives a general idea on why you never dereferenciate a pointer to an object in Objective-C.
However, concerning the specific case of NSString
literals, this is not what's happening in reality. While the structure described below is still sound and it may work that way, what's actually happening is that the space for a string literal is allocated at compile time, and you get its address back. This is true for string literals, since they are immutable and constant. For the sake of efficiency therefore each literal is allocated only once.
As a matter of fact
NSString * a = @"Hello";
NSString * b = @"Hello";
NSLog(@"%@ %p", a, a); // Hello 0x1f4958
NSLog(@"%@ %p", b, b); // Hello 0x1f4958
ORIGINAL ANSWER
Because it will be translated to
message = [[NSString alloc] initWithUTF8String:"Hello"]];
which will boil down to
message = objc_msgSend(objc_msgSend(objc_getClass("NSString"), @selector(alloc)), @selector(initWithUTF8String:), "Hello");
Now if we take a look to the signature of objc_msgSend
id objc_msgSend(id theReceiver, SEL theSelector, ...)
we see that the method returns an id
type, which in Objective-C is the object type. But how is id
actually defined?
typedef struct objc_object {
Class isa;
} *id;
id
is defined as a pointer to an objc_object
struct.
So in the end @"string"
will translate in a function call that will produce a pointer to an object (i.e. an objc_object
struct, if you prefer), which is exactly what you need to assign to message
.
Bottom line, you assign pointers, not objects.
To better clarify the last concept consider this
NSMutableString * a = [NSMutableString stringWithString:@"hello"];
NSMutableString * b = a;
[a setString:@"hola"];
NSLog(@"%@", a); // "hola"
NSLog(@"%@", b); // "hola"
If you were assigning objects, b
would have been a copy of a
and any further modification of a
wouldn't have affected b
.
Instead what you get is a
and b
being two pointers to the same object in the heap.