user2517182
user2517182

Reputation: 1299

How do I cast void* to NSString without getting a Runtime Error, in Objective C?

There are many posts about handling casting a void*. I have have followed their instructions. However I am getting a runtime error when trying to cast a void* to NSString*.

I am pretty sure I am missing something simple. :-)

Consider the following code:

NSString* testString = @"This is a test";
NSLog(@"voidTest = %@", [self voidTest:&testString]);

And the following function:

- (NSString*)voidTest:(void*)testString
{
    NSString* value = (__bridge NSString *)(testString);
    return value;
}

When this code is run, the first line in the function gives me the the following error:

Thread 1: EXC_BAD_ACCESS(code=1, address=0x1200000070)

Any help with this would be greatly appreciated.

Upvotes: 1

Views: 3210

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

The problem is the extra dereference: you are passing a pointer to NSString*, which is itself a pointer.

You can fix this either by adding an extra dereference in voidTest:

NSString* value = *((__unsafe_unretained NSString **)(testString));

or by passing testString instead of &testString in the caller.

Neither of these solutions is ideal, because it forces a cast. Generally speaking, void* should be reserved for calls to C functions. When calling Objective-C to Objective-C, you could use the id type instead, which tells the compiler that you are passing an Objective-C object.

-(void)voidTest:(void*)ptr {
    NSString *val = *((__unsafe_unretained NSString **)(ptr));
    NSLog(@"%@", val);
}

-(void)testVoid {
    NSString *str = @"Hello";
    [self voidTest:&str];
}

Upvotes: 8

user2517182
user2517182

Reputation: 1299

@dasblinkenlight, thanks for getting me going in the right direction.

So in the end the following code is what worked.

The function call:

NSString* testString = @"This is a test";
NSLog(@"voidTest = %@", [self voidTest:(__bridge void *)(testString)]);

The function:

- (NSString*)voidTest:(void*)testString
{
    NSString* value = (__bridge NSString *)(testString);
    return value;
}

Upvotes: -1

Related Questions