无法将Swift 4字符串传递给Obj-C ++-[_ SwiftValue dataUsingEncoding:]:无法识别的选择器已发送到实例 [英] Trouble passing Swift 4 String to Obj-C++ -[_SwiftValue dataUsingEncoding:]: unrecognized selector sent to instance

查看:130
本文介绍了无法将Swift 4字符串传递给Obj-C ++-[_ SwiftValue dataUsingEncoding:]:无法识别的选择器已发送到实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些像这样的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 a String
  • 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 a NSString * 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆