2015-02-23 82 views
0

我已经实现了一个必须等​​待特定过程完成的类(使用NSWorkspace openFile:withApplication开始)。runningApplications返回终止的进程?

我试过[[NSWorkspace sharedWorkspace] runningApplications],并不会返回正在运行的进程的数组。但它仍然包含我要监视的进程,即使此进程不再运行(它从活动监视器中消失,并且不会显示在top命令中)。

有没有人有线索如何正确监视进程?检查terminated属性或processIdentifier属性并不能解决问题(terminated仍然为NO,并且processIdentifier包含有效的查找过程ID)。

+0

'[[ [NSWorkspace sharedWorkspace] runningApplications]在您调用它时返回正在运行的应用程序。我以这种方式测试它:1.我启动了计算器应用程序。 2.调用'[[NSWorkspace sharedWorkspace] runningApplications]'3.退出计算器应用程序4.调用runningApplications。 它工作完美:计算器应用程序出现在第2步,但不是在第4步。我不知道你是如何使用它。 – Sudo 2015-02-23 15:10:19

+0

我用一个do-while循环尝试了它,它只包含一个'[NSThread sleepForTimeInterval:2]'和while语句中正在运行的进程的检查。 – Alex 2015-02-24 06:32:06

+1

似乎正是这种睡眠引起的问题。 – Alex 2015-02-24 08:39:32

回答

2

-runningApplications只在主运行循环被允许运行时更新。如果您正在轮询或以其他方式保持主运行循环忙碌,则永远不会更新。

NSWorkspace

到NSRunningApplication类的性质类似,当主运行的循环是在普通模式下运行,此属性将只更改。不要使用轮询,而是使用键值观察来通知对此数组属性的更改。

从任何应用程序的线程调用此方法是安全的。该方法以原子方式返回其值。

该方法返回的值可以使用键值观察来观察。

我可能只是抓取NSRunningApplication本身,KVO观察它的terminated属性。只要确保主运行循环可以继续。

如果你有一个GUI应用程序,这是正常的事态;只是从你的方法返回。如果这是一个命令行应用程序,那么根据我的经验与NSWorkspace合作的最佳解决方案是将[NSApp run]放入main()以像GUI应用程序一样启动它。这通常意味着创建应用程序委托并将大部分代码放在那里,而不是在main()中。当您通常退出程序时,请致电[NSApp terminate:nil]

当然,你也可以仅仅通过手runMode:beforeDate:自己运行的主要runloop。 (我记得对我来说使用NSApplication效果更好,但是我不记得原因,可能是听通知,所以也许手动运行循环就没问题了。)

+0

看起来像'NSRunningApplication'对象不能被观察到。所附的观察员从未被触发(我不知道为什么)。 – Alex 2015-02-24 08:30:41

+0

但是''runMode:beforeDate:'你的提示完成了。非常感谢! – Alex 2015-02-24 08:38:48