tags:

views:

1332

answers:

1

Looking at the JSON-Framework source, it makes heavy use of pass by reference in many of the parser method signatures. i.e.

@interface SBJsonParser ()
  - (BOOL)scanValue:(NSObject **)o;
  - (BOOL)scanRestOfArray:(NSMutableArray **)o;
  - (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o;
@end

This ends up being used something like this:

id o;
[self scanValue:&o];
// Do something with o

- (BOOL)scanValue:(NSObject **)o {
  // Cut down for brevity
  return [self scanRestOfDictionary:(NSMutableDictionary **)o];
}

- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o {
  // Cut down for brevity
  *o = [NSMutableDictionary dictionaryWithCapacity:7];
  [*o setObject:@"value" forKey:@"key"];
  return YES;
}

What are the benefits to this approach?


EDIT: I'm asking more from a design point of view. I understand what pass by reference is, I'm just wondering when it's appropriate to use it. The design used in SBJsonParser is similar to the API used in NSScanner:

- (BOOL)scanUpToString:(NSString *)stopString intoString:(NSString **)stringValue;

To me, this implies that the string which was scanned is secondary to needing to know if something was scanned. This is in contrast to the API used by NSString:

+ (id)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;

In that API, the contents of the file is the primary concern, and the NSError reference is used to pass back an error in the event that something goes wrong.

Just after some general thoughts on which API is most appropriate, when.

+2  A: 

Those are "output" parameters. They allow the called method to assign a value to your local variable "o". In other words, you're not passing in a reference to an object, but a reference to a local variable.

In your case, the methods return a BOOL to indicate success or failure; therefore, they use output parameters to return other values and objects.

Darren
See my clarifications at the bottom of the question.
Nathan de Vries