如果存在,请从NSRunningApplication _only_删除观察者

我正在设计辅助工具。

它将获得具有文本焦点的当前窗口:

self.app_with_kb_focus = NSWorkspace.sharedWorkspace.frontmostApplication;

然后一个窗口出现在顶部,长话短说:将文本放置在粘贴板上。覆盖窗口被破坏后,原始窗口将被重新激活并粘贴文本。

问题是在准备接收原始窗口之前粘贴文本:请参见Inject keyboard event into NSRunningApplication immediately after foregrounding it

一个丑陋的解决方案是使用计时器。

更漂亮的解决方案是将观察者附加到self.app_with_kb_focus的{​​{1}}属性:

isactive

然后观察者将处理粘贴,并将其自身删除:

[self.app_with_kb_focus addobserver: self
                         forKeyPath: @"isactive"
                            options: 0
                            context: (void *)self.app_with_kb_focus ];

[textFieldWindow close];

// return previous foreground application to foreground
[self.app_with_kb_focus activateWithOptions: NSApplicationactivateAllWindows];

这通常可以正常工作,但偶尔会导致以下警告+崩溃:

  

2019-11-11 08:19:51.029956-0700 chi [40721:2568959]当观察者仍在向对象注册时,该对象将被释放。将来可能会崩溃。有人正在观察以下一个或多个属性:活动。

     

2019-11-11 08:19:51.030281-0700 chi [40721:2568959] [常规]释放了类NSRunningApplication的实例0x600002c42980,同时仍向其注册了键值观察器。当前观察信息:    上下文:0x600002c42980,属性:0x600000cec450>   )

由于我无论如何都不会终止应用程序,这必须来自原始文件

- (void) observeValueForKeyPath: (NSString *) keyPath
                       ofObject: (id) object
                         change: (NSDictionary *) change
                        context: (void *) context
{
    if( [keyPath isEqualToString: @"isactive"] )
    {
        NSRunningApplication* fg_app = (__bridge NSRunningApplication *)context;

        [fg_app removeObserver: self
                    forKeyPath: @"isactive"];

        paste( 0 );
}

...已在附加观察者后之后重新分配,但在观察者回调触发之前之前/没有

因此,在此行之前,我想说:“如果有附加的观察者,请将其删除。”

如何用代码做到这一点?

drahcir88t 回答:如果存在,请从NSRunningApplication _only_删除观察者

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3122830.html

大家都在问