swift - 将 Swift 4 字符串传递给 Obj-C++ 时遇到问题 - [_SwiftValue dataUsingEncoding:]:无法识别的选择器已发送到实例
问题描述
我有一些像这样的 Objective-C++ 代码:
// 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++ 代码调用时效果很好!然而,当斯威夫特参与其中时......
func mySwiftFunc(text: String) {
myObjcClassInstance.myMethod(text)
}
这似乎也很简单。编译器的翻译层自动将 SwiftString
与 Objective-C++ 的NSString *
. 不幸的是,这是错误的......它似乎将它与名为_SwiftValue
. 然后它被传入,我尝试调用dataUsingEncoding:
它,但显然_SwiftValue
没有这样的选择器,所以我得到了这个崩溃:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue dataUsingEncoding:]: unrecognized selector sent to instance 0x7f9ca7d63ee0'
我不知道如何解决这个问题。我不能NSString
在 Swift 中使用,只是将其传递下去,因为编译器要求我传递一个 Swift String
。
有没有办法解决这个问题?
这些解决方案中的任何一个都可以:
- 强制生成的 Swift 标头接受 a
NSString *
而不是 aString
- 一种
_SwiftValue
从 Objective-C++ 中将 a 转换为数据的方法 - 任何让编译器或运行时知道在尝试发送消息之前
_SwiftValue
将其转换为 a 的标志NSString *
- 等等
环境
- ObjC++ 代码位于 Swift 代码引用的模块化框架内;它们没有一起编译。
- ObjC++ 模块使用 Xcode 8.3.3 编译,Swift 代码使用 9.2 编译。
- 可能存在其他差异;这些项目中有很多活动部件。
解决方案
我会尝试
func mySwiftFunc(text: String) {
myObjcClassInstance.perform(#selector(NSSelectorFromString("myMethod:"), with: text as NSString)
}
如果这不起作用,请尝试:
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:"
字符串依赖,但我跳过了铸造体操,因为它不是问题的本质。
推荐阅读
- php - PHP 到 pdf 的转换在包含文件中显示错误
- python - 如何将某些列的每组重复值放入新的单独数据框中
- python-3.x - 我想如何将 int 转换为 str
- here-api - 为“命名地点”类型的 ID 获取“图像媒体类型”
- python - pip 无法安装软件包,即使它存在于 pypi 服务器上
- c++ - Google Mock - 模拟对象无法在 Visual Studio 中构建
- wordpress - 如何动态更改联系表单 7 提交显示消息
- c# - 在 UWP 中动态更改 ThemeResources
- angular - 如何在 MatDialog 中显示带有某些控件的 FormGroup
- react-native - 如何通过 React Native 测试库中的可访问性角色和标签选择元素