我花了很长时间,但我终于想通了。可能有更简单的方法可以做到这一点,但我发现我需要在 .mm 文件中创建一个 C++ 类,作为 boost::signals2 信号和 Objective-C 回调函数之间的桥梁:
在 CPPToCocoaModelMessageCallbacks.h 中:
/* ------------------------------------------------------------------------
class CPPToCocoaModelMessageCallback -
--------------------------------------------------------------------------- */
class CPPToCocoaModelMessageCallback
{
public:
CPPToCocoaModelMessageCallback( PMD_Signal_Messenger<PrefEvent> *theSignalClass,
int whichPrefIdxToObserve,
id pObjCClass,
SEL pObjCMethod);
~CPPToCocoaModelMessageCallback();
void CallBackMessage(PrefEvent* pPrefEvent);
private:
id fpObjCClass;
SEL fpObjCMethod;
ls_index fWhichPrefIdxToObserve;
boost::signals2::connection fTheConnection;
}; // CPPToCocoaModelMessageCallback
在 CPPToCocoaModelMessageCallbacks.mm
/* ------------------------------------------------------------------------
CPPToCocoaModelMessageCallback - CONSTRUCTOR
whichPrefIdxToObserve - the preference idx to observe
Pass the id and selector of the Objective-C/C++ object & method to be
called.
--------------------------------------------------------------------------- */
CPPToCocoaModelMessageCallback::CPPToCocoaModelMessageCallback(PMD_Signal_Messenger<PrefEvent> *theSignalClass, int whichPrefIdxToObserve, id pObjCClass, SEL pObjCMethod)
: fpObjCClass (pObjCClass),
fpObjCMethod (pObjCMethod),
fWhichPrefIdxToObserve (whichPrefIdxToObserve)
{
fTheConnection = theSignalClass->ObserveSignal(&CPPToCocoaModelMessageCallback::CallBackMessage, this);
}
/* ------------------------------------------------------------------------
~CPPToCocoaModelMessageCallback - DESTRUCTOR
Pass the id and selector of the Objective-C/C++ object & method to be
called.
--------------------------------------------------------------------------- */
CPPToCocoaModelMessageCallback::~CPPToCocoaModelMessageCallback()
{
fTheConnection.disconnect();
}
/* ------------------------------------------------------------------------
CPPToCocoaModelMessageCallback::CallBackMessage -
Handles single and range-type preference change events.
--------------------------------------------------------------------------- */
void CPPToCocoaModelMessageCallback::CallBackMessage(PrefEvent* pPrefEvent)
{
// Only make the callback if this event is the preference we're observing
if (pPrefEvent->GetChangedPrefIdx() == fWhichPrefIdxToObserve) {
[fpObjCClass performSelector:fpObjCMethod];
}
}
///////////////////////////////////////// /////////////////////////
在你的 controller.mm 中:
// set up messaging from Model. The message callback functions must be destructed in dealloc.
// I've done this in awakeFromNib but it could be elsewhere
- (void)awakeFromNib {
PMD_Signal_Messenger<MyEventKind>* theModelClass = GetMyModelClassPointer();
displayMenuPrefChangedCallBack = new CPPToCocoaModelMessageCallback(theModelClass, kAppPrefDictionaryDisplayShortDef, self, @selector(displayMenuChanged));
}
/* ------------------------------------------------------------------------
displayMenuChanged - this gets called when the model fires a signal
(via CPPToCocoaModelMessageCallback::CallBackMessage())
--------------------------------------------------------------------------- */
- (void) displayMenuChanged
{
NSLog(@"displayMenuChanged\n");
// DO SOMETHING TO RESPOND TO THE SIGNAL (in this case I'm reloading an NSWebView):
[self reloadWebViewText];
}
///////////////////////////////////////// /////////////////////////
与模型类结合用于信号观察者的类:
PMD_Signal_Messenger.h:
/* ------------------------------------------------------------------------
class PMD_Signal_Messenger<MyEventKind> -
This class is designed to be multiple inherited with various
Model classes.
--------------------------------------------------------------------------- */
template <class MyEventKind>
class PMD_Signal_Messenger {
public:
PMD_Signal_Messenger() { }
~PMD_Signal_Messenger() { }
template<typename Fn, typename Obj>
boost::signals2::connection ObserveSignal(Fn callback, Obj &object) {
return fSignalObservers.connect(boost::bind(callback, object, _1));
}
protected:
boost::signals2::signal<void (MyEventKind*)> fSignalObservers; // all observers of my preference changes
private:
PMD_Signal_Messenger(const PMD_Signal_Messenger& thePMD_Signal_Messenger) { assert(false); } // prevent copy constructor
};
在要发出模型更改信号的 .cpp MODEL 文件中:
// construct theEvent (your own struct) and fire the signal with your event structure that gets passed to CPPToCocoaModelMessageCallback::CallBackMessage()
MyEventKind theEvent(someUsefulParams);
fSignalObservers(&theEvent);