Cannot understand NSError/NSObject pointer passing behavior

前端 未结 2 1776
花落未央
花落未央 2021-01-05 17:13

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.

相关标签:
2条回答
  • 2021-01-05 17:46

    So, after initialisation on the first line, error is a pointer to an NSError object.

    In the first log, you are logging the address at which that pointer is held. That's the effect of the & address-of operator. Anyway, that is the address gets passed into the doSomething method.

    You're passing in: pointer -> pointer -> nserror-object.

    But notice the double indirection in the signature of doSomething. The autoreleasing annotation makes it hard to spot, but its NSError **.

    So the compiler takes your parameter and 'unwraps' it twice.

    It starts as pointer -> pointer -> nserror-object. Then after the first indirection it becomes pointer -> nserror-object. Then after the second indirection it becomes nserror-object.

    Ergo, you are logging two different things. The first is the address of the pointer to the nserror-object. The second is the address of the nserror-object itself.

    EDIT: @MANIAK_dobrii points out that the object pointed to by error is itself different in the before and after case.

    That's true. If an error occurs in doSomething then it creates an entirely new NSError instance in the else clause. It then loads that back into the error pointer. That's why you would see two different addresses, afterwards the error pointer is pointing to another object entirely.

    0 讨论(0)
  • 2021-01-05 18:05

    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.

    0 讨论(0)
提交回复
热议问题