Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

objective c - Why dereferencing a NSString pointer is not necessary?

In the example

NSString *message = @"Hello";
message = @"World";

If message is just a pointer why don't I need to explicitly say whatever is in message is now equal to string or *message = @"World"; like in C?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...