使用std :: string隐式构造NSString

时间:2014-04-22 18:42:28

标签: c++ ios objective-c nsstring objective-c++

使用Objective-C ++时,我经常发现自己使用initWithCString从std :: string转换为NSString。为简化过程,我在NSString上创建了一个类别,如下所示:

@implementation NSString (NSStringFromCPP)

+(NSString*)stringFromCppString:(std::string)cppString
{
    return [[NSString alloc] initWithCString:cppString.c_str() encoding:NSStringEncodingConversionAllowLossy];
}


-(std::string)cppString
{
    return std::string([self cStringUsingEncoding:NSStringEncodingConversionAllowLossy]);
}

@end

这允许在两个方向上相当容易地在NSString和std :: string之间进行转换。似乎必须有一种方法可以隐式地从std :: string转换为NSString。我知道在Objective-C中没有构造函数这样的东西,所以如何在不必使用stringFromCppString

的情况下完成以下操作
-(void)something:(NSString*)someString
{
    NSLog(@"%@", someString);
}


-(void)activity
{
    std::string activityName = "Calculator";
    [self something:[NSString stringFromCppString:activityName]];
}

在大多数情况下,使用NSString可以将使用std :: string的代码与代码分开。但是,会发生相当多的桥接,并且代码会在整个地方stringFromCppString分散注意力。

2 个答案:

答案 0 :(得分:2)

Objective-C没有提供任何隐式转换类型的工具。事实上,它甚至没有构建对象的概念 - 因为所有对象都是由指针引用的,所以强制转换只是指针转换而不会改变底层数据。语言提供将对象转换为其他类型的唯一方法是在对象上调用方法。

答案 1 :(得分:2)

你应该在你的Obj-C方法中传递std::string const &作为参数的类型。

+(NSString*)stringFromCppString:(std::string const &)cppString;

另外,不要忘记,当编译为.mm时,你可以使用普通的C ++,所以你可能想要考虑像重载这样简单的东西......

std::string
cppString(char const *s)
{
  return s;
}

std::string const &
cppString(std::string const &s)
{
  return s;
}

std::string
cppString(NSString *s)
{
  return [self cStringUsingEncoding:DESIRED_ENCODING];
}

另一种方式......

NSString *
objcString(char const *s)
{
  return [NSString stringWithCString:s encoding:DESIRED_ENCODING];
}

NSString *
objcString(std::string const &s)
{
  return objcString(s.c_str());
}

NSString *
objcString(NSString *s)
{
  return s;
}

现在,只要你想要一个C ++ std :: string,只需要调用cppString,只要你想要一个Obj-C NSString,只需要调用objcString,你真的不需要关心"真实"字符串是......

或者,您可以使用转换运算符创建自己的字符串包装器...这样做也很简单。

但是,一般来说,你可能希望你的C ++是C ++,你的ObjC是ObjC,并使用.mm作为轻量级胶水。