При работе с 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]];
}
В большинстве случаев код, использующий std :: string, может быть отделен от кода с помощью NSString. Тем не менее, существует достаточное количество мостов, и код становится отвлекающим stringFromCppString
повсюду.
Objective-C не предоставляет никаких средств для неявного преобразования между типами. На самом деле, он даже не имеет концепции приведения объекта — поскольку все объекты ссылаются на указатели, приведение — это просто приведение указателя, которое не изменяет базовые данные. Единственный способ, которым язык обеспечивает преобразование объекта в какой-либо другой тип, — это вызов метода для объекта.
Вы должны пройти std::string const &
как тип для параметра в вашем методе Obj-C.
+(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 в качестве легкого клея.