在Objective C中如何在不获取运行时错误的情况下将void *转换为NSString?

时间:2014-05-19 16:06:32

标签: objective-c ios7 casting nsstring void-pointers

有很多关于处理无效*的帖子。我已按照他们的指示行事。但是,当尝试将void *转换为NSString *时,我收到运行时错误。

我很确定我错过了一些简单的东西。 : - )

请考虑以下代码:

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

以下功能:

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

运行此代码时,函数中的第一行会出现以下错误:

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

对此的任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:5)

问题是额外的取消引用:你传递的指针是NSString*,它本身就是一个指针。

您可以通过在voidTest:

中添加额外的解除引用来解决此问题
NSString* value = *((__unsafe_unretained NSString **)(testString));

或在调用者中传递testString而不是&testString

这些解决方案都不是理想的,因为它会强制演员。一般来说,void*应保留用于调用C函数。在将Objective-C调用到Objective-C时,您可以使用id类型,它告诉编译器您正在传递Objective-C对象。

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

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

答案 1 :(得分:-1)

@dasblinkenlight,谢谢你让我朝着正确的方向前进。

所以最后下面的代码才有用。

函数调用:

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

功能:

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