Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an NSString from an NSInvocation using setReturnValue

When I set the return value of an NSInvocation to be an NSString, the invoker is receiving an NSCFString.

In my case I'm mocking to pull a bundle path from file included by unit tests:

[[[_bundlePartial stub] andDo:^(NSInvocation *invocation) {
    NSString* resourceName = [invocation getArgumentAtIndexAsObject:2];
    NSString* type = [invocation getArgumentAtIndexAsObject:3];
    NSString* path = [[NSBundle bundleForClass:self.class] pathForResource:resourceName ofType:type];
    if (!path)
    {
        path = [_bundleOriginal pathForResource:resourceName ofType:type];
    }
    [invocation setReturnValue:(void*)path];
}] pathForResource:OCMOCK_ANY ofType:OCMOCK_ANY];

I call it like this:

NSString* jsonPathInBundle = [[NSBundle mainBundle] pathForResource:self.fileName ofType:self.fileExtension];

Unfortunately I'm getting back a NSCFString. This makes some sense, since my NSString is backed by a NSCFString, but when I lose the bridge I can no longer call NSString instance methods on the object. Is there a way I can return the value as an NSString?

like image 306
Ben Flynn Avatar asked Mar 05 '14 20:03

Ben Flynn


People also ask

What is the purpose of returning an NSString?

Returns an NSData object containing a representation of the receiver encoded using a given encoding. This NSString object. The fastest encoding to which the receiver may be converted without loss of information.

What is an NSString object?

An NSString object encodes a Unicode-compliant text string, represented as a sequence of UTF–16 code units.

How do I create an NSString from an NSData source?

Creates an NSString from an NSData source. The byte buffer. Use this encoding to intepret the byte buffer. An NSString created by parsing the byte buffer using the specified encoding.

Is NSString native-endian or non-native?

When creating an NSString object from an array of unichar values, the returned string is always native-endian, since the array always contains UTF–16 code units in native byte order.


1 Answers

After examine the OCMock code, I found my problem. Effectively a typo but its subtle enough that I don't think it's worth deleting the question.

Change:

[invocation setReturnValue:(void*)path];

To:

[invocation setReturnValue:&path];

My original way of writing this destroyed a layer of abstraction because the NSString was being treated as an address, rather than using its actual address.

like image 117
Ben Flynn Avatar answered Sep 20 '22 09:09

Ben Flynn