9

I realize that this is similar to an existing post here, What's the Point of (NSError**)error?, but my question is a little different. I understand how the double pointer works, and how this is the common iOS API error pattern. My question is more around the single pointer, and why this code doesn't work:

- (BOOL)someMethodWithError:(NSError *)error
{
  ...
  if( errorOccured )
  {
    NSError *e = [[[NSError alloc] initWithDomain:@"" code:1 userInfo:nil] autorelease];
    error = e;
    return NO;
  }

  return YES;
}

implemented using:

NSError *error = nil;
if( ![someObj someMethodWithError:error] )
{
  NSLog(@"Error: %@", [error localizedDescription]);
}

Why doesn't the assignment in the method implementation reassign the pointer to the new NSError object?

Community
  • 1
  • 1
Eric
  • 1,688
  • 2
  • 15
  • 13

4 Answers4

9

I find that it helps to think of a pointer as just an integer. (That's what it is.)

Look at your example with an int.

-(BOOL)someMethodWithError:(int)error
{
     error =100;
     return NO;
}

That integer is pass by value. after that function is called error will not change.

   error  = 123;
  [self someMethodWithError:error];
  //error is = 123;

The pointer is the same thing. It's pass by value.

  NSError * error; //this assigns this to a value in memory.
  NSLog(@"%p",error);
  [self someMethodWithError:error];
  NSLog(@"%p",error); // the value of error will not have changed.

if you want the pointer to change you need to send in a pointer to that pointer and change it. It is confusing but draw yourself a diagram of memory and think about it. :)

madmik3
  • 6,975
  • 3
  • 38
  • 60
  • 1
    Excellent explanation madmik. Thank you. It totally makes sense now realizing that the pointer is pass by value. – Eric Feb 22 '12 at 06:04
  • 1
    @madmik3: It can be dangerous to think of a pointer as "just an integer". A pointer is a variable that contains an address. Just because C allows you to use arithmetic operations like `++` on pointers does not mean pointers will behave like integers. For example, if you `++` a variable of type `int` you will have added 1 to its value. However, if you `++` a variable of type `int *` *you will have added 4 to its value*. – pje Oct 12 '12 at 03:14
  • I'm not suggesting that you consider them the same thing, but if you look at how they respond to passing variables it becomes clear why sometimes you need a double pointer. It's just for the example. :) – madmik3 Oct 12 '12 at 13:36
4

It's all about the double pointer.

Why isn't the new value showing? Because you never modified the contents of the object which you initialized as nil. To do that you would have needed to use a reference to the memory location where the nil value was stored (a pointer to the pointer), not just a copy of the nil value (which is what you are passing using the single pointer).

This is a really common thing to do in C where some of the output of a function is "returned" through a pointer in the input arguments.

El Developer
  • 3,345
  • 1
  • 21
  • 40
0

This is how the C language works. You might like to take a look at this question and answer: C double pointer, which is basically the same thing in a different guise.

Community
  • 1
  • 1
Tim Potter
  • 2,437
  • 21
  • 31
0

Well error that somemethodWithError has is different pointer which is containing the address of the error from where someMethodWithError is get called. so when you assign any object to error pointer of someMethodWithError it will not reflect in the error pointer of method from where it is called

it's like

NSError * error1 = obj1;
NSError * error2 = error1;

and afterward if you assign any new object to error2 like

error2 = obj2;

it will not change the pointer value of error1 and it will still point to obj1

Sunil Pandey
  • 7,042
  • 7
  • 35
  • 48