我想改变一些对象(标签,按钮......)的属性,我是用c ++代码创建的。所以我需要一种运行ViewController-class-internal方法的方法。
有没有正确的方法呢?还有其他可能吗?
我尝试过使用回调,但ViewController类中的全局和内部之间始终存在这种障碍。提前谢谢!
编辑: 由于我不知道如何使用c ++代码访问swift类,我无法提供任何适当的示例,但我想到了类似的东西(伪代码):
在c ++中:
int main(){
say_hello();
}
并在Swift中:
class ViewController: NSViewController {
@IBOutlet weak var label: NSTextField!
func say_hello(){
label.stringValue = "Hello"
}
}
答案 0 :(得分:2)
这是一个过于简单的示例,说明如何使用Objective-C ++包装器完成此操作,如Richard所建议的那样。这里没有解决内存管理和线程安全方面以及许多其他问题。在此示例中,Swift和C ++类实例之间存在一对一的关系。此外,Swift对象指针用作标识符来决定哪个Swift对象应该接收通知。这有点危险,请参阅下面的代码中的注释。使用Objective-C ++包装器中更复杂的数据结构来维护Swift和C ++对象之间的连接,可以轻松解决这种危险并支持除1对1之外的关系。
首先,这是一个触发Swift代码更改的C ++类:
typedef void (*cb_t)(const char *, void *);
class MyClassCPP {
public:
MyClassCPP(cb_t callBack, void * p) : myCallBack(callBack), clientPtr(p) {}
void doWork(); // perform some work and invoke the callback
private:
cb_t myCallBack;
void * clientPtr;
};
void MyClassCPP::doWork() {
myCallBack("C++ code at work...", clientPtr);
}
这是一个Objective-C ++包装器接口,应该通过桥接头直接或间接地使Swift代码可见。请注意,它不引用任何C ++类型。
@class SwiftClass; // forward declaration
// can't include *-Swift.h in a header
@interface OCWrapper : NSObject
-(instancetype)init:(SwiftClass * )sc;
-(void)requestWorkFromCPP;
@end
这是包装器实现。它确实引用了C ++类型。我们不能提供Swift全局函数作为C ++代码的回调,但我们可以为此提供Objective-C ++全局函数。
// Extension that deals with C++ specifics that can't be visible to Swift
@interface OCWrapper ()
{
MyClassCPP * myClassCPP;
}
@end
void callBack(const char * msg, void * swiftClient)
{
// Danger: what if swiftClient does not point to a SwiftClass instance?
[(__bridge SwiftClass*)swiftClient sayHello:
[[NSString alloc] initWithBytes: msg length:strlen(msg)
encoding:NSASCIIStringEncoding]];
}
@implementation OCWrapper
-(instancetype)init:(SwiftClass * )sc
{
myClassCPP = new MyClassCPP(callBack, (__bridge void*)sc);
return self;
}
-(void)requestWorkFromCPP{
myClassCPP->doWork();
}
@end
以上内容应该在Objective-C ++文件中。创建一个Objective-C文件,然后将其重命名为.mm
扩展名。您还需要包含* -Swift.h头文件,因此Objective-C ++可以使用Swift类型。
最后,这里有一些通过Objective-C ++包装器使用C ++代码的Swift代码:
// This is like your Swift view controller
class SwiftClass : NSObject
{
var label = "[Empty]"
var name : String;
init(name : String) {
self.name = name
}
func sayHello(greeting : String) {
label = "SwiftClass named " + name + " received greeting: " + greeting
}
}
...
let sc = SwiftClass( name : "Zero")
let ocWrapper = OCWrapper(sc)
let sc1 = SwiftClass( name : "One" )
let ocWrapper1 = OCWrapper(sc1)
ocWrapper1.requestWorkFromCPP()
print("The label value from C++: \(sc1.label)")
ocWrapper.requestWorkFromCPP()
print("The label value from C++: \(sc.label)")
...