如何在使用Objective-C++的C++类中向NSNotificationCenter添加观察者?

8

我有一个C++类,最近将其从*.cpp重命名为*.mm以支持Objective-C。因此,我可以添加以下Objective-C代码。

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(notificationHandler:) 
                                                 name:@"notify"
                                               object:nil];
  • 我该如何/能够在c++中编写notificationHandler方法?
  • 设置addObserver:self属性会起作用吗?
3个回答

18

或者你也可以直接使用区块,如下:

[
    [NSNotificationCenter defaultCenter] addObserverForName: @"notify"
    object: nil
    queue: nil
    usingBlock: ^ (NSNotification * note) {
        // do stuff here, like calling a C++ method
    }
];

1
这看起来很棒。但是你如何将其移除? - prideout
非常干净的方式,请看此链接:https://developer.apple.com/documentation/foundation/nsnotificationcenter/1411723-addobserverforname?language=objc - Pervez Alam

16
你需要一个Objective-C类来处理Objective-C通知。Core Foundation来拯救你了!
在任何地方开始监听通知,例如你的构造函数:
static void notificationHandler(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo);

MyClass::MyClass() : {
    // do other setup ...

    CFNotificationCenterAddObserver
    (
        CFNotificationCenterGetLocalCenter(),
        this,
        &notificationHandler,
        CFSTR("notify"),
        NULL,
        CFNotificationSuspensionBehaviorDeliverImmediately
    );
}

完成后,在你的析构函数中实现:

MyClass::~MyClass() {
    CFNotificationCenterRemoveEveryObserver
    (
        CFNotificationCenterGetLocalCenter(),
        this
    );
}

最后,一个处理分发的静态函数:

static void notificationHandler(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    (static_cast<MyClass *>(observer))->reallyHandleTheNotification();
}

Ta da!


哦,太酷了。我一直在想这个核心基础是什么意思。谢谢伙计。 - valmo
这些 CF* 函数是否被认为是“无需付费的桥梁”,可以连接到“正常”的NSNotificationCenter? - johnbakers
不,CFNotificationCenterNSNotificationCenter不是toll-free bridged。因此,两者中的自定义实例将无法在另一个API中使用。但是,如果您在任一标准中心(例如CFNotificationCenterGetLocalCenter()[NSNotificationCenter defaultCenter])中使用并发布通知,则通知将发布到两组侦听器(即接口是不同的,但底层系统相同)。 - Jonathan Grynspan

4

由于Objective-C方法处理方法调用与C ++不同,因此您无法将C ++方法添加为观察者。 您必须有一个Objective-C类(使用@interface Class .. @end声明)来响应这些方法。

您唯一的选择是在Objective-C类中包装您的C ++类,或者只是拥有一个非常轻量级的包装器,该包装器仅具有对对象的引用,并在通知到达时静态调用方法。


我很担心答案会是那样的。感谢您的回复。 - valmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接