我有一些像这样的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 ++代码调用时,效果很好!但是,当Swift参与进来时...
func mySwiftFunc(text: String) {
myObjcClassInstance.myMethod(text)
}
这似乎也很简单。编译器的翻译层自动将Swift的String
桥接到Objective-C ++的NSString *
。不幸的是,这是错误的……它似乎将其桥接到称为_SwiftValue
的东西上。然后它传入了,我尝试在其上调用dataUsingEncoding:
,但是显然_SwiftValue
没有这样的选择器,所以我遇到了崩溃:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue dataUsingEncoding:]: unrecognized selector sent to instance 0x7f9ca7d63ee0'
我不知如何解决此问题。我不能在Swift中使用NSString
并将其传递下去,因为编译器要求我需要传递一个Swift String
。
这些解决方案中的任何一个都可以:
NSString *
而不是String
_SwiftValue
转换为来自Objective-C ++的数据的方法_SwiftValue
转换为NSString *
之前尝试向其发送消息答案 0 :(得分:1)
我会尝试
this.createBoxes().then(function() {
let template = document.querySelector('#pool');
let app = document.querySelector(".app");
for(let child of template.childNodes) {
let clone = child.cloneNode(true);
app.appendChild(clone);
}
});
如果那行不通,请尝试:
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)
}
的情况下可能会实现字符串依赖性,但是我跳过了强制转换体操,因为这不是问题的本质。