首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CFNotificationCenter中的NSWorkspace通知

CFNotificationCenter中的NSWorkspace通知
EN

Stack Overflow用户
提问于 2012-01-31 21:51:26
回答 1查看 1.8K关注 0票数 2

我们正在做一个Qt项目,有一些Mac特定的代码需要添加。我们需要注册一个事件,在一个示例程序中,我们通过使用:

代码语言:javascript
复制
[[NSNotificationCenter defaultCenter] addObserver:self
                                   selector:@selector(notificationHandler:) 
                                   name:NSWorkspaceDidDeactivateApplicationNotification
                                   object:nil];

由于我们可以在Qt上的mm文件中直接使用它,因此我们采取的方法如下:

代码语言:javascript
复制
MyClass::MyClass() : {
    // do other setup ...

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

"NSWorkspaceDidDeactivateApplicationNotification"??的字符串是什么或者我们如何将自己附加到这个特定的通知中?

我们尝试了NSGod的方法,但是因为没有Objective-C代码可以添加到带有Qt的.h中,所以我们添加了一个私有成员,它的类是在mm文件中定义的,它包含实际的逻辑。如下所示:

SelectedStuffManager.h

代码语言:javascript
复制
class MacWrap;

class SelectedStuffManager
{
  public:
   ....
    doSomething();

    MacWrap* d;

  private:
   ....
};

SelectedStuffManager.mm

代码语言:javascript
复制
@class MDWorkspaceWatcher;

class MacWrap
{
    public:
        MacWrap();
        ~MacWrap();

        void  applicationDeactivated(NSNotification * notification);

        SystemEventsApplication *systemApplication;
        NSRunningApplication *runApp;

        private:
           MDWorkspaceWatcher *workspaceWatcher;
};
MacWrap::MacWrap() {
      this->workspaceWatcher = [[MDWorkspaceWatcher alloc] initWithMyClass:this];
}

MacWrap::~MacWrap() {
      [this->workspaceWatcher release];
}

void  MacWrap::applicationDeactivated(NSNotification* notification)
{
    // guardar el id del proceso para utilizarlo luego
    runApp = [[notification userInfo] valueForKey:@"NSWorkspaceApplicationKey"];
    NSString *systemEventsASppName = [runApp bundleIdentifier];
    if( [ systemEventsASppName isNotEqualTo:@"com.yo.SelectedText"])
    {
        systemApplication = [SBApplication applicationWithBundleIdentifier:systemEventsASppName];
        NSLog(@"Launched. %@",systemEventsASppName);
    }

}

@interface MDWorkspaceWatcher : NSObject {

     MacWrap  *manager;
}

- (id)initWithMyClass:(MacWrap*)obj;
- (void)didDeactivateApp:(NSNotification *)notification; @end

@implementation MDWorkspaceWatcher
- (id)initWithMyClass:(MacWrap*)obj {
    if ((self = [super init])) {
       manager = obj;

       [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
                selector:@selector(didDeactivateApp:)
                name:NSWorkspaceDidDeactivateApplicationNotification
                object:nil];
    }
    return self;
}

- (void)dealloc {
    [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
    [super dealloc];
}

- (void)didDeactivateApp:(NSNotification *)notification {
   manager->applicationDeactivated(notification);
}
@end

SelectedStuffManager::SelectedStuffManager()
{
    d = new MacWrap();
}
SelectedStuffManager::doSomething()
{
    if ([[d->runApp localizedName] isEqualTo: @"something"]) --> here it fails, bad memory access
    {
       ...
    }
}

似乎有人同时释放了runApp和systemApplication,所以我们得到了一个空指针或坏内存。这是如何或为什么会发生的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-01 01:32:48

我不相信你能随心所欲地去做。首先,NSWorkspace使用自己的NSNotificationCenter,这与+defaultCenter返回的默认NSNotificationCenter不同。

我不相信有一个严格的CF-等同于那些NSWorkspace调用。可能存在高级别的基于碳的等价物,但它们在64位中不可用,因此应该避免使用。

您应该能够使用一个小的Objective-C helper类接收通知并将它们转发到C++类,如以下代码所示:

编辑:已更新以从头文件中删除任何Objective-C。只需使用可以在.mm文件中转换的通用void *指针即可。

.h:

代码语言:javascript
复制
//@class MDWorkspaceWatcher;

class MyClass {
   private:
      // MDWorkspaceWatcher *workspaceWatcher;
      void *workspaceWatcher;
   public:
       MyClass();
       ~MyClass();

       // const void didActivateApp(NSNotification *notification) const;
       // const void didDeactivateApp(NSNotification *notification) const;
       const void didActivateApp(void *anNSnotification) const;
       const void didDeactivateApp(void *anNSnotification) const;

};

.mm:

Objective-C部分:

代码语言:javascript
复制
@interface MDWorkspaceWatcher : NSObject {
    MyClass    *myClass;
}
- (id)initWithMyClass:(MyClass *)aMyClass;
@end

@implementation MDWorkspaceWatcher
- (id)initWithMyClass:(MyClass *)aMyClass {
    if ((self = [super init])) {
       myClass = aMyClass;
       [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
                selector:@selector(didActivateApp:)
                name:NSWorkspaceDidActivateApplicationNotification
                object:nil];
       [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
                selector:@selector(didDeactivateApp:)
                name:NSWorkspaceDidDeactivateApplicationNotification
                object:nil];
    }
    return self;
}
// very important:
- (void)dealloc {
    [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
    [super dealloc];
}
- (void)didActivateApp:(NSNotification *)notification {
   myClass->didActivateApp(notification);
}
- (void)didDeactivateApp:(NSNotification *)notification {
   myClass->didDeactivateApp(notification);
}
@end

C++部件:

代码语言:javascript
复制
MyClass::MyClass() {
      this->workspaceWatcher = [[MDWorkspaceWatcher alloc] initWithMyClass:this];
}

MyClass::~MyClass() {
      [(MDWorkspaceWatcher *)this->workspaceWatcher release];
}

MyClass::didActivateApp(void *anNSnotification) {
     NSDictionary *appInfo = [(NSNotification *)anNSnotification userInfo];          
     NSLog(@"appInfo == %@", appInfo);

}

MyClass::didDeactivateApp(void *anNSnotification) {
     NSDictionary *appInfo = [(NSNotification *)anNSnotification userInfo];          
     NSLog(@"appInfo == %@", appInfo);

}

注意,NSDictionary是用CFDictionaryRef免费桥接的,所以如果您更喜欢C而不是Objective-C,那么您可以简单地将appInfo NSDictionary转换为CFDictionaryRef,然后调用CF函数来获取字典的内容。

请注意,通知中心拥有appInfo字典(换句话说,它将自动发布),因此您不应该像使用CFCreate*/CFCopy*-related代码那样对它调用CFRelease()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9080619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档