【问题标题】:djinni - pointers and circular references between C++ and swift/objective C/javadjinni - C++ 和 swift/objective C/java 之间的指针和循环引用
【发布时间】:2017-10-12 19:36:42
【问题描述】:

我有两个 djinni 接口,一个在 Swift/objective C/java SwiftObj 中实现,一个在 C++ CPPObj 中实现。

SwiftObj = interface +o +j {
    someSwiftMethod();
}

CPPObj = interface +c {
    static create(swiftObj: SwiftObj): CPPObj;
    someCPPMethod();
}

它们都有一个指向彼此的指针,因此SwiftObj 将能够调用CPPObjsomeCPPMethod(),反之亦然:CPPObj 将能够从SwiftObj 调用someSwiftMethod()

迅速:

  • 类变量:var myCPPObj: SwiftObj!
  • 创作:myCPPObj = MyCPPObj.create(self)
  • 用法:myCPPObj.someCPPMethod()

在 c++ 中:

  • 类变量:shared_ptr<SwiftObj> mySwiftObj_;
  • 用法:mySwiftObj_->someSwiftMethod();

所以这里的问题是,由于循环引用,这些对象没有被垃圾收集(我尝试并删除了循环引用并且它们得到了 GC)。

但后来我尝试将其中一个指针设置为弱。在 C++ 中:weak_ptr<SwiftObj> mySwiftObj_; ... 但这使得 mySwiftObj_ 立即被 GC,即使它实际上仍然存在于 swift 中。当我将 swift 指针设置为弱而 C++ 设置为强时,也发生了同样的事情。

那么我该如何处理这种情况呢? (除了手动将这些指针之一设置为空)。关于指针如何在 djinni 中实际工作的任何见解?

谢谢!

【问题讨论】:

  • 问题不在于他们如何在 djinni 中工作,djinni 根本没有指针。您的问题是您可能不知道智能指针在 C++ 中是如何工作的。我说的对吗?
  • 没有。如果全部在 C++ 中,设置 A ---strong---> B 和设置 B ---weak--> A 将解决循环指针问题。但是由于 djinni 在中间,如果我有一个弱指针,它会立即被 GC。
  • djinni 不会返回弱指针,而是您将共享它返回给弱指针。你知道吗?
  • 我知道并且我已经尝试过这样做。阅读帖子。
  • 我已经阅读了这篇文章,我确实在评论它。只是指出您没有使用正确的智能指针这一事实。

标签: c++ ios objective-c swift djinni


【解决方案1】:

不幸的是,没有一种弱引用/指针可以理解跨语言的所有权,Djinni 也没有尝试添加。 C++ 和 Swift 中可用的弱语义只知道同一语言中的引用,这就是您看到即时 GC 行为的原因。它是 Djinni 生成的代理对象,它被弱持有,并且变得未使用,但是一旦代理消失,它就会释放真实的对象。

我认为最简单的方法是将 Swift 对象拆分为两个对象,我们称它们为 Owner 和 Listener。在您的示例中,只有 Listener 需要是 Djinni 对象,并实现 someSwiftMethod()。也许您还有其他原因让 Owner 也成为 Djinni 界面。如下设置您的所有权图。原谅 ASCII 艺术:Swift 在左边,C++ 在右边。

                  <- Swift|C++ ->

  SwiftOwner ------------------------> CppObj
    ^    |                               |
    |    |                               |
 (weak)  |                               |
    |    v                               |
  SwiftListener <------------------------+

在这种情况下,循环和弱引用都仅限于 Swift,因此将按您的预期工作,SwiftListener 可以根据需要将方法转发给SwiftOwner。该模型针对这些对象的外部使用来自 Swift 的情况进行了优化。此类用户应持有对SwiftOwner 的引用。如果您的主要用途是在 C++ 中,您可以反转图片,或者您可以让外部 C++ 对象持有对 SwiftOwner 的强引用。无论哪种方式,SwiftOwner 都没有(强)循环引用,一旦它被释放,其他两个对象也将被释放。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多