I am now confused by pointer to pointer even though I've read Why does NSError need double indirection? (pointer to a pointer) and NSError * vs NSError ** and much more.
I've done some thinking and still got some questions.
Here I wrote this:
NSError *error = [NSError errorWithDomain:@"before" code:0 userInfo:nil];
NSLog(@"outside error address: %p", &error];
[self doSomethingWithObj:nil error:&error];
In order to test the above NSError
method, I wrote this:
- (id)doSomethingWithObj:(NSObject *)obj error:(NSError *__autoreleasing *)error
{
NSLog(@"inside error address: %p", error);
id object = obj;
if (object != nil)
{
return object;
}
else
{
NSError *tmp = [NSError errorWithDomain:@"after" code:0 userInfo:nil];
*error = tmp;
return nil;
}
}
But I found that the two logging addresses are different. Why is that?
2016-08-19 19:00:16.582 Test[4548:339654] outside error address: 0x7fff5b3e6a58
2016-08-19 19:00:16.583 Test[4548:339654] inside error address: 0x7fff5b3e6a50
Shouldn't they be the same since that was just a simple value copy? If they should be different, how can pointer to pointer end up pointing to the same NSError
instance?
The variable in the caller has type NSError*
. The address has type NSError* *
. The function expect NSError* __autoreleasing *
. Therefore the compiler creates a hidden variable of type NSError* __autoreleasing
, copies the NSError*
into the hidden variable before the call, and copies it back after the call to get the semantics of __autoreleasing right.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With