Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

warstory91

macrumors newbie
Original poster
Apr 20, 2010
10
10
Hey guys, I have a quick question about the pointer syntax used in Obj-C.

When you deal with numbers, pointers work this way:

int *y;
y = &x;
and then to reference the x variable through y you use *y

Now with strings, it apparently works this way:

NSString *s1;
s1 = @"Test";
and then to reference the string you just use s1

Now my questions is, for strings, why do you just do s1 = @"Test" instead of something like s1 = &@"Test" and to use the value of the string, you just mention the variable name instead of *(variable name)? Does it have something to do with Strings being an object and numbers not? And if so why the difference in syntax?
 
Does it have something to do with Strings being an object and numbers not? And if so why the difference in syntax?

Yes, it's for that reason exactly. Just for your own edification, instead of "numbers" say "primitives".

You only refer to Objects via pointers. This is simply how the Object model was set up in Objective-C. In C++, you can have pointers to Objects or local copies of Objects, and you access them differently based on which you have in a particular case. The concept of a stack-local Object does not exist in Objective-C. They all live on the heap, and you get to all of them via a pointer.

So a message pass in Objective-C always takes the pointer to the object. You never apply the * operator to an Object pointer. That's just the way the language was designed.

@"" NSString literal syntax is just special, just like java.lang.String literals are special in Java. When they appear in your code, this is ultimately going to lead to an Object being created. @"" syntax is going to give you an NSString *. You can pass messages right to NSString's created this way, such as:
Code:
NSUInteger x = [@"Test" length];

-Lee
 
From a strictly linguistic point of view (using your example),

*y means the location that variable y points to.

if a method definition is written

- (void)setIntValueFrom: (int *)aValue;

that means the method wants a pointer to an int. That is what y is. If you try to send the method *y, the compiler will try to use the value that y points to, not the pointer, and since that value is an int, it will spit up all over you.

For the @"whatever" literal, you can think of it as equivalent to [NSString stringWithCString: @"whatever" encoding: NSUTF8StringEncoding]
 
Thanks Lee for the help and for comparing Obj-C to C++ since C++ is what I am learning in school right now and thats where most of the confusion was originating from.

For reference, it is definitely worth using the forum search. I came up with all of these that address this (and some other interesting things):

My fault, I'll look around first next time. https://forums.macrumors.com/threads/625899/ is pretty much the same question i was asking (i kinda like ur explanation in that thread better)
 
Actually, you're asking two questions in one: Why is there an @-sign, and why is there not an &.

Let's rephrase for clarity: why is it
Code:
int x = 42;
int* y = &x;
but
Code:
const char* s = "Hello";
and not
Code:
const char* s = &"Hello";
since s is obviously a pointer?

The answer is that in C (and C++, and Objective-C), a string doesn't really exist; it's a (zero-terminated) array of characters. What's worse, arrays don't really exist either, and they are approximated by a pointer to its first member (pointers really exist!) along with convenient syntax to address elements at an offset from that pointer.

A "string literal" (a bunch of characters between quotes) is a conventient way to put an array-of-characters in your code (with the zero-termination taken care of by the compiler). Since it's already an array, you don't need to take the address of it using the &-operator.

The second part is that an NSString is not a simple C-string; it's a proper Objective-C object. Since it's so convenient to be able to construct strings with literals, Objective-C adds a nice shorthand like Sydde and jared_kipe explained; that's what the @ is for.

Hope that helps.
 
Now my questions is, for strings, why do you just do s1 = @"Test" instead of something like s1 = &@"Test" and to use the value of the string, you just mention the variable name instead of *(variable name)? Does it have something to do with Strings being an object and numbers not? And if so why the difference in syntax?

When you have a number like 5, that number is the thing you are interested in. So you can store it like "int x = 5;". You can make a pointer that points to the variable by writing "int* y = &x;". So far all easy.

When you have objects like NSString, you don't really care about the things in the object. Cocoa creates the object for you and puts it away somewhere. Instead of working with the object itself, Cocoa just gives you a pointer to where the object is, that is an "NSString*". So most of the time you treat an NSString* just as you would treat an int.

@"Something" is just a shortcut that the compiler understands for creating an NSString object with the text "Something" inside and giving you an NSString* that points to that object.

And just as you write "int x = 5;" you write "NSString* a = @"xxx";". And just like you can have a pointer that points to x, you can have a pointer that points to a: "NSString* *b = &a;".
 
And just like you can have a pointer that points to x, you can have a pointer that points to a: "NSString* *b = &a;".

So in that case you would have a string pointer b that points to another string pointer a which then points to a string object?

EDIT: Also in your example, would you have to use *b from then on to refer to a, or could you just use b
 
So in that case you would have a string pointer b that points to another string pointer a which then points to a string object?

EDIT: Also in your example, would you have to use *b from then on to refer to a, or could you just use b

b is not a string pointer. It is a pointer to a string pointer. The pattern is:

something x = ...;
something *y = &x;

If "something" is "int" then you have:

int x = ...;
int *y = &x;

If "something" is "NSString*" then you have

NSString* x = ...;
NSString* *y = &x;
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.