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?

brock
  • 2,302
  • 7
  • 27
  • 30
  • 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 http://stackoverflow.com/questions/822487/how-does-an-underscore-in-front-of-a-variable-in-a-cocoa-objective-c-class-work – Vervious May 03 '12 at 00: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 *. – thundersteele May 04 '12 at 01:19

2 Answers2

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 *.

RyanWilcox
  • 13,890
  • 1
  • 36
  • 60
  • 1
    `@private` has always existed in Objective-C (at least under Apple). The new one is `@package`. http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF127 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”. – Peter Hosey May 03 '12 at 02:28
  • 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 :) – RyanWilcox May 03 '12 at 03:53
  • 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.) – abarnert May 03 '12 at 21:12
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*

Daniel
  • 1,079
  • 1
  • 11
  • 25