Placement of the asterisk in Objective-C

Viewed 10777

I have just begun learning Objective-C, coming from a VB .Net and C# .Net background. I understand pointer usage, but in Objective-C examples I see the asterisk placed in several different places, and search as I might, I have not been able to find an answer as to why this is. Every search I try turns up all kinds of explanations about pointers (which I really don't need), but not a single mention of the reasons/effects of the different placements of the asterisk. Here are some examples I've seen:

NSString *string;
NSString * string;
(NSString *) string;
NSString* string;

What do these different positions of the asterisk mean? I'm sure it's a simple answer but it's frustrating not being able to find it in any of the Apple tutorial and reference documentation or online so far.

Can someone please end my misery and answer this perplexing question? Thanks!

14 Answers
1.  NSString *string;
2.  NSString * string;
3.  (NSString *) string;
4.  NSString* string;

1, 2 and 4 are exactly identical. It's all style. Pick whatever you want, or mix it up.

Choice #3 has another meaning also, it's used in casting. For example:

t = (NSString *)string ;

will cast string to an NSString pointer.

But choice #3 is the syntax you'd probably use in a .h file or in the function definition in a .m file. Inside an actual function, in code which is "run" it has a different meaning.

There is no difference — it's a matter of style. They all declare a variable called string that's a pointer to an NSString. The parentheses are necessary in some contexts (particularly method declarations) in order to clarify that it's a type declaration.

1.  NSString *string;
2.  NSString * string;
3.  (NSString *) string;
4.  NSString* string;

1,2 and 4 are equivalent. The C language (and the Objective-C superset of C) specify a syntax that is insensitive to white space. So you can freely add spaces where you choose as a matter of style. All relevant syntax is delimited by non-whitespace characters (e.g. {, }, ;, etc.) [1].

3 is either a type cast (telling the C compiler to use the NSString* type regardless of the declared type of string. In Objective-C, type casting of object instances is rarely necessary. You can use the id type for variables that can reference instances of any object type.

In method declarations, syntax 3 (sometimes without the ending semicolon) is used to declare the type of method parameters. An Objective-C method may look like this:

- (void)myMethodThatTakesAString:(NSString*)string;

In this declaration, the type of the argument named string is type NSString* (the leading - indicates an instance method as oppose to a class method). A method declaration with more than one parameter might look like this:

- (void)myMethodTakingAString:(NSString*)string andAnInteger:(NSInteger)intParam;

[1] This is compared to languages like Python which use whitespace as a block delimeter.

it doesn't matter where you put your asterisk, all statements create pointers of type NSString.

when using multiple variable names in one line you have to write the asterisk for each variable though.

NSString * nsstring, * nsstring2;

there actually all equivalent: a pointer to an nsstring!!

1, 2 and 4 are equivalent and define a pointer to an NSString. My personal preference is to emulate K&R as much as possible, so I like to use NSString *string;

(NString*)string; though a valid statement, doesn't really do anything by itself.

$ cat foo.m
#include <Cocoa/Cocoa.h>

void foo()
{
    NSString *string;

    (NSString*) string;  // doesn't do anything
    42;   // doesn't do anything either
}

$ gcc -Wall -c foo.m
foo.m: In function 'foo':
foo.m:7: warning: statement with no effect
foo.m:8: warning: statement with no effect
Related