0

I recently picked up the BigNerdRanch book on Cocoa for Mac OSX and am looking for a good explanation around the use of asterisks * and underscores _ that seem to be inconsistently used throughout the language. Some examples:

These appear to be functionally equivalent:

NSString* myString; NSString *myString; 

Sometimes new variables get an underscore, while others dont:

NSString _myString; NSString myString; 

And sometimes it gets all crazy:

NSString *myString; NSString *_myString; 

I've also seen variations with asterisks in methods:

- (void)speechSynthesizer:(NSSpeechSynthesizer *)sender willSpeakWord:(NSRange)characterRange ofString:(NSString *)string; 

So what is the functional use of the asterisk or the underscore, when should you use (or not use) either, and when should they be used in combination?

2
  • 5
    * means a pointer (read up on C programming) and '_' is just another alphanumeric character that doesn't really mean anything (except as a guideline for variable names that some programmers like to use). See stackoverflow.com/questions/822487/… Commented May 3, 2012 at 0:51
  • Just for clarification: The second set of variable definitions are wrong, and will not compile or crash. Objects (i.e. subclasses of NSObject must be defined with a pointer (the * thingy)). Variables which are not objects (e.g. int, float, char) must be defined without *. Commented May 4, 2012 at 1:19

2 Answers 2

2

The * indicate a pointer, which all Objective-C objects are. (You pass around pointers to these objects in memory). At a basic level these are normal C pointers. If I remember correctly You could access some data in an Objective-C object by going object->data, just like you do with pointers to C structs.

The _ is a Cocoa (and some other languages) convention, meaning "a piece of data that should be considered private to this object".

Objective-C has a @private declaration, but it's also a relatively new addition to the language - if your code is more than 2 or 3 years old (or targeting much older versions of OS X) it might not use @private

Because of this initial lacking of language infrastructure, the _ is (often) used by the Cocoa community to mark "Hey, you probably shouldn't set or read this directly, please".

So:

  • When dealing with Objective-C classes you always need the * to follow the class name (like NSString), because they are always pointers. I'm confused about your NSString somestring line in your code - either that'll generate a complier warning or will crash when you try to use it
  • The _ indicates private data. You would do something like NSString* _name in a @interface section of your Objective-C class. You would use _name by itself if you were calling or operating on that data in a method in your class.

So say you created a Student class:

// Student.h @interface Student : NSObject { NSString* _name; } - (NSString*) name_as_caps; @end // Student.m @implementation Student - (NSString*) name_as_caps { return [_name uppercase]; } 

Here we declare a class with a "private" data member: _name. Our Student class needs to return this capitalized for some reason, so we created a method to do that, where we use _name and call the uppercase method on it.

We needed to refer to the type (or class name) or _name a few times here: once, to declare the variable. For name_as_caps we needed to say: this method returns a pointer to an NSString object, thus we used NSString *.

Sign up to request clarification or add additional context in comments.

3 Comments

@private has always existed in Objective-C (at least under Apple). The new one is @package. developer.apple.com/library/mac/documentation/Cocoa/Conceptual/… Also, it's worth noting that the _ doesn't mean anything to the compiler; it's just part of the name, used conventionally by programmers to mean (to each other) “this is private”.
Ahh good point about @private - I was thinking about methods, not data. Regardless, Apple uses _ for their private variables, so the gist is still correct :)
Actually, in the classic runtime you're explicitly not supposed to use the _ prefix for your variables, because they may collide with Apple-defined variables in superclasses. (That's why most books use a _ suffix instead.) However, in the modern runtime, that collision isn't a problem, and Apple now recommends using the _ prefix when you're defining a slot variable to back up a property (especially with synthesize.)
0

As an addendum to Ryan's answer, when you see something like

-(void)speechSynthesizer:(NSSpeechSynthesizer *)sender willSpeakWord:(NSRange)character RangeofString:(NSString *)string; 

the things like (NSSpeechSynthesizer *)sender just state the type of the argument - in this case NSSpeechSynthesizer*

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.