我想向我的C ++客户端代码公开ObjC通知处理程序。
我就是这样


我将一个ObjC对象(称为X)包装在C ++对象中。
X观察通知并注册一个回调(称为F)。
F将ObjC结构从通知转换为C ++对应结构,并调用用户注册的全局C ++回调函数(称为FF)。转换后的C ++结构成为FF的输入参数。


现在的问题是,参数的原始ObjC结构很复杂,包含需要翻译的多层ObjC对象。

在我这一边,包装观察者F不需要做任何特别的事情,只需调用客户端的FF。

此时,我的翻译更合适的策略是什么?

我是不是该:


将这些结构转换为所有成员的最底层,以便我可以使用等效的C ++结构作为参数,或者
创建一个C ++类,将这些参数包装到一个对象中,并向用户公开该类的接口,以便他们可以在C ++实现中使用这些C ++包装的参数,或者
放弃包装的想法,要求用户在ObjC中编码并直接注册自己的观察器功能?


我的目标用户是iOS开发人员,也可能不是Android开发人员。

最佳答案

您可以在.mm实现文件中混合使用c ++和Objective-c ++。这意味着您可以为引用您的c ++所有者的Objective-c ++类提供c ++ lambda(或块)。

像这样的东西:

Implementation.mm:

@interface Shim : NSObject
{
  std::function<void>() _notify;
}
@end

@implementation Shim
- void register_cpp(std::function<void>() f)
{
  _notify = std::move(f);
}

- (void) my_handler()
{
  if(_notify)
    _notify();
}
@end

struct cpp_class::impl {
  impl()
  : _shim([Shim alloc[init]])
  {
    _shim.register_cpp(std::bind(&impl::callback, this));
  }

private:
  void callback() {
    // do callback here;
  }
  Shim* _shim;
};

cpp_class::cpp_class()
: _impl(new impl)
{
}

cpp_class::~cpp_class()
{
  delete _impl;
}


header.h:

struct cpp_class{
  cpp_class();
  ~cpp_class();

private:
  struct impl;
  impl* _impl;
};


实际上,您将要小心以确保在执行回调(对象的弱项(如weak_ptr :: lock(),enable_shared_from_this等))时对象仍然存在,因为objective-c喜欢将回调放入线程的运行循环(基本上是队列) ),这意味着您的c ++对象可以在回调到达之前消失-但是此代码应为您提供正确的思路。

关于c++ - 通用目标到C++的翻译策略,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26242092/

10-12 14:49