openfrog
openfrog

Reputation: 40755

What's the Point of (NSError**)error?

Example: The -save: method of NSManagedObjectContext is declared like this:

- (BOOL)save:(NSError **)error

Since NSError is already a class, and passing a pointer would actually have the effect of modifying this object inside the implementation of -save:, what's the point of passing a pointer to a pointer here? What's the advantage/sense?

Usage example:

NSError *error;
if (![managedObjectContext save:&error]) {
    // Handle the error.
}

Upvotes: 8

Views: 4052

Answers (6)

MacMark
MacMark

Reputation: 6549

If you just passed in a pointer, all the method could do would alter the already existing NSError object that you are pointing to.

You cannot alter an NSError object.

NSError is immutable. That's the reason you need the pointer to the NSError variable. You can only create a brand new NSError. Thus you change the pointer to point to your newly created NSError.

Upvotes: 2

Darren
Darren

Reputation: 25619

It is what some people refer to as an "out" parameter.

You're not passing a pointer to an NSError object, you're passing a pointer to a local variable. This gives the called method the ability to modify your local variable; in this case, to assign it to an NSError instance.

Perhaps what's confusing is that the local variable you're passing to save: is itself a pointer, so the variable type ends up being a pointer to a pointer.

Bottom line, it's a pointer to a local variable, and it works the same whether the local variable is an int or an NSError*.

Upvotes: 12

Dave DeLong
Dave DeLong

Reputation: 243156

@Anon is correct. I'll add: This is the Cocoa way to produce errors, in place of throwing exceptions.

In your example, you have:

NSError *error = nil;
if (![managedObjectContext save:&error]) {
    // Handle the error.
}

Immediately after the call to save:, if there was an error, then the save: method will have created a new NSError object, and changed your error variable to point from nil to the new error object. That way you can examine the NSError object yourself and respond appropriately to it.

IMO, this is cleaner than throwing an exception (which in my philosophy should only be done when something catastrophic and unrecoverable happens).

Upvotes: 7

Peter B
Peter B

Reputation: 26388

The advantage is that you don't have to create the NSError object. As the documentation states:

"A pointer to an NSError object. You do not need to create an NSError object."

Upvotes: 3

Matt Greer
Matt Greer

Reputation: 62057

If you just passed in a pointer, all the method could do would alter the already existing NSError object that you are pointing to.

By passing in a pointer to a pointer, it can create new NSError objects and leave you with a pointer that points to them.

Upvotes: 16

Anon.
Anon.

Reputation: 60013

It allows the method to allocate a new NSError and change the pointer to point to it, rather than having to modify the NSError already pointed-to (what if it's not big enough?)

Upvotes: 4

Related Questions