Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting id to pointer to an NSError pointer (NSError **)

I have an NSError ** stored in an array (so I can get it as such array[0]). I'm trying to cast it into a variable:

NSError * __autoreleasing *errorPointer = (NSError * __autoreleasing *)array[0];

so I can access the underlying object as *errorPointer.

However, Xcode complains that Cast of an Objective-C pointer to 'NSError *__autoreleasing *' is disallowed with ARC. Is there any way to get to this object without turning off ARC?

like image 518
Stepan Hruda Avatar asked Feb 17 '23 11:02

Stepan Hruda


1 Answers

Neither that stub:withBlock: method or any of its supporting infrastructure could be simply stuffing a double pointer into an NSArray. The array won't take non-objects, and a pointer to an object is not an object. There's something else going on.

This obviously requires some digging into the code to figure out. Where does the value get put into the array? That's in -[KWStub processInvocation:], and it's done apparently using a method added to NSInvocation by OCMock, getArgumentAtIndexAsObject:. In that method, the invocation uses a switch to check the type of the argument that is requested, and boxes it up if necessary.

The relevant case here is the last one, where the argument type is ^, meaning "pointer". This sort of argument is wrapped up in an NSValue; therefore, the array recieved by your Block actually contains, not the double pointer itself, but an NSValue representing the outer pointer. You just need to unbox it.

That should look like this:

NSValue * errVal = array[1];
NSError * __autoreleasing * errPtr = (NSError * __autoreleasing *)[errVal pointerValue];
like image 187
jscs Avatar answered May 20 '23 04:05

jscs