无法将Swift 4字符串传递给Obj-C ++-[_ SwiftValue dataUsingEncoding:]:无法识别的选择器已发送到实例 [英] Trouble passing Swift 4 String to Obj-C++ -[_SwiftValue dataUsingEncoding:]: unrecognized selector sent to instance
问题描述
我有一些像这样的Objective-C ++代码:
I have some Objective-C++ code like this:
// header
@interface MyObjcClass
- (void) myMethod: (NSString *) text;
@end
// implementation
@implementation MyObjcClass
- (void) myMethod: (NSString *) text
{
someInternalObject->useWstring(nsStringToWstring(text))
}
std::wstring nsStringToWstring(const NSString * text)
{
NSData * data = [text dataUsingEncoding: NSUTF32LittleEndianStringEncoding];
// and then some other stuff irrelevant to this question
return std::wstring(pointerToNewString, pointerToNewString + stringLength);
}
@end
到目前为止直截了当;对我来说似乎很好.当从Objective-C和Objective-C ++代码中调用时,效果很好!但是,当Swift参与进来时...
Straightforward so far; seems fine to me. And works great when called from Objective-C and Objective-C++ code! However, when Swift gets involved...
func mySwiftFunc(text: String) {
myObjcClassInstance.myMethod(text)
}
这似乎也很简单.编译器的翻译层自动将Swift的String
桥接到Objective-C ++的NSString *
.不幸的是,那是错误的……它似乎将其桥接到名为_SwiftValue
的东西.然后传入了,我尝试在其上调用dataUsingEncoding:
,但是显然_SwiftValue
没有这样的选择器,所以我遇到了崩溃:
This also seems straightforward. The compiler's translation layer automatically bridge's Swift's String
to Objective-C++'s NSString *
. Unfortunately, that's false... it seems to bridge it to something called _SwiftValue
. And then that's passed in and I try to call dataUsingEncoding:
on it, but apparently _SwiftValue
doesn't have such a selector, so I get this crash:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue dataUsingEncoding:]: unrecognized selector sent to instance 0x7f9ca7d63ee0'
我不知该如何解决这个问题.我不能在Swift中使用NSString
并将其传递给我,因为编译器要求要求我传递一个Swift String
.
I'm at a loss for how to resolve this. I can't use NSString
in Swift and just pass that down because the compiler requires that I pass a Swift String
.
所有这些解决方案都可以:
Any of these solutions will do:
- 强制生成Swift标头以接受
NSString *
而不是String
- 一种从Objective-C ++内将
_SwiftValue
转换为数据的方法 - 任何标志,让编译器或运行时知道在尝试发送消息之前将
_SwiftValue
转换为NSString *
- 等
- Force generated Swift header to accept a
NSString *
instead of aString
- A way to turn a
_SwiftValue
into data from within Objective-C++ - Any flags that let the compiler or runtime know to translate that
_SwiftValue
to aNSString *
before trying to message it - etc.
- ObjC ++代码在Swift代码引用的模块化框架内;它们没有一起编译.
- ObjC ++模块使用Xcode 8.3.3编译,而Swift代码则使用9.2编译.
- 可能还有其他差异;这些项目中有很多活动部件.
推荐答案
我会尝试
func mySwiftFunc(text: String) {
myObjcClassInstance.perform(#selector(NSSelectorFromString("myMethod:"), with: text as NSString)
}
如果那行不通,请尝试:
If that won't work try:
func mySwiftFunc(text: String) {
let selector : Selector = NSSelectorFromString("myMethod:")
let methodIMP : IMP! = myObjcClassInstance.method(for: selector)
unsafeBitCast(methodIMP,to:(@convention(c)(Any?,Selector,NSString)->Void).self)(myObjcClassInstance,selector,text as NSString)
}
在没有选择器名称的情况下可能会实现"myMethod:"
字符串相关性,但是我跳过了强制转换体操,因为这不是问题的本质.
Probably possible without selector name "myMethod:"
String dependence, but I skipped the casting gymnastics as it's not the essence of the problem.
这篇关于无法将Swift 4字符串传递给Obj-C ++-[_ SwiftValue dataUsingEncoding:]:无法识别的选择器已发送到实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!