views:

122

answers:

2

Sometimes I encounter code that has *, sometimes **. Can anyone explain what they mean in Objective C? (I used to be a Java programmer, with experience in C/C++.)

+6  A: 

The * denotes that you are using a pointer to a variable, and is most commonly used to store a reference to an Objective-C object, objects which can only live on the heap and not the stack.

Pointers are not a part of Objective-C exclusively, but rather a feature of C (and therefore its derived languages, of which Objective-C is one of them).

If you are questioning the difference between * and **, the first denotes a pointer, whereas the second denotes a pointer to a pointer; the advantage of the latter to the former is that when passing in an object using ** in a method parameter, the method can then change this parameter and the new value is accessible in the calling method.

Perhaps the most common use of ** in Cocoa is when using NSError objects. When a method is called that can return an NSError object on failure, the method signature would look something like this:

- (id)someMethodThatUsesObject:(id)object error:(NSError**)error;

What this means is that the calling function can pass in a pointer to an NSError object, but someMethodThatUsesObject: can change the value of error to another NSError object if it needs to, which can then be accessed by the calling method.

This is often used as a workaround for the fact that functions can only return one value.

Perspx
still don't get the ideas of **, why don't give the pointer of the error ONLY. (I mean * only.)
Tattat
@Tattat: Function/method parameters in C/Obj-C are `bycopy` *only*; pointers are the only way of passing methods `byref`; as you are passing an object pointer (`NSError *`) by reference, this necessitates the double-pointer (`NSError **`). (That is to say; local modifications to the value of `error` will not be carried over into the caller; so if a pointer to an unusable object is passed in, well, you're boned.)
Williham Totland
Because if the argument is an `NSError*` (and not an `NSError**`) then `someMethodThatUsesObject:` can't change the local value of `error` that is passed in from the calling method. There's a good explanation here http://stackoverflow.com/questions/2067563/whats-the-point-of-nserrorerror/2067727#2067727
Perspx
As @Williham Totland points out, the key is copying of method parameters.
Perspx
+1  A: 

A * in Objective-C means exactly the same as in C; and you'll usually see it (or not) in these situations:

// Method signatures:
// Here the asterisk (*) shows that you have a pointer to an NSString instance.
+ (NSString *)stringWithString:(NSString *)aString;

// Method signatures, part two:
// Here the double asterisk (**) signifies that you should pass in a pointer
// to an area of memory (NSError *) where outError can be written.
- (BOOL)writeToURL:(NSURL *) atomically:(BOOL) error:(NSError **)outError;

// Method signatures make for good examples :)
// Here the asterisk is hidden; id is a typedef for void *; and it signifies that
// a pointer to some object of an indeterminate class will be returned
- (id)init;

// And a forth example to round it all out: C strings!
// Here the asterisk signifies, you guessed it, a pointer! This time, it's a
// pointer to the first in a series of const char; terminated by a \0, also known
// as a C string. You probably won't need to work with this a lot.
- (const char *)UTF8String;

// For a bit of clarity, inside example two, the outError is used as follows:
// Here the asterisk is used to dereference outError so you can get at and write
// to the memory it points to. You'd pass it in with:
// NSError *anError;
// [aString writeToURL:myURL atomically:YES error:&anError];
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atom error:(NSError **)outError {
  // do some writing, and if it went awry:
  if (outError != NULL)
    *outError = [NSError errorWithName:@"NSExampleErrorName"];
  return NO;
}
Williham Totland