选择文件/目录后立即关闭 NSOpenPanel
我是 NSOpenPanel/NSSavePanel/NSPanel 的新手。我正在使用 NSOpenPanel 选择一个目录,我的应用程序将遍历该目录的文件并进行一些相当耗时的处理。
我可以在面板上调用 -close ,但这不会将焦点返回到主窗口。我读过很多关于“关闭”面板的内容 - 但我还没有找到任何“关闭”而不是“关闭”面板或窗口的方法。
难道只是我需要生成一个后台线程(NSOperation)?
这就是我的 -chooseDidEnd:returnCode:contextInfo:
-(void) chooseDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
[panel orderOut:self];
[panel release];
if (returnCode == NSFileHandlingPanelOKButton)
{
[progressIndicator startAnimation:self];
[self doLotsOfTimeConsumingWork:[[panel URL] path]];
[progressIndicator stopAnimation:self];
}
}
虽然 NSOpenPanel 确实消失了,但我的 NSProgressIndicator 没有动画,并且主窗口直到 -doLotsOfTimeConsumingWork: 完成之后才激活。
更新 刚刚查看了 NSOperationSample 代码,看起来就是这样。
I am new to NSOpenPanel/NSSavePanel/NSPanel. I am using NSOpenPanel to choose a directory whose files my app will iterate over and do some fairly time-consuming processing.
I can call -close on the panel, but that does not return focus to the main window. I have read a lot about "dismissing" the panel - but I haven't found any methods that "dismiss" rather than "close" a panel or a window.
Is it just that I need to spawn a background thread (NSOperation)?
This is what my -chooseDidEnd:returnCode:contextInfo:
-(void) chooseDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
[panel orderOut:self];
[panel release];
if (returnCode == NSFileHandlingPanelOKButton)
{
[progressIndicator startAnimation:self];
[self doLotsOfTimeConsumingWork:[[panel URL] path]];
[progressIndicator stopAnimation:self];
}
}
While the NSOpenPanel does go away, my NSProgressIndicator does not animate and the main window doesn't come alive until after -doLotsOfTimeConsumingWork: completes.
Update
Just looked at NSOperationSample code, and it is looking like that's the way to go.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
两点注意:
首先,在 Cocoa 中,事件处理和绘制发生在主线程上。因此,在那里同步调用冗长的方法从来都不是一个好主意(这就是 UI 无响应的原因)。
因此,是的,您应该通过此方法将计算量大的任务移交给辅助线程,就像任何
IBAction
一样。其次,在该方法中调用
[panel release]
违反了Cocoa的对象所有权规则!因此,如果您在没有该调用的情况下泄漏了面板,则应该在创建面板的方法中修复该问题。Two notes:
First, in Cocoa, the event handling and drawing happens on the main thread. Hence it is never a good idea to synchronously call lengthy methods there (which is the reason for your unresponsive UI).
So yes, you should hand off computationally expensive tasks to a secondary thread from this method, like from any
IBAction
.Second, calling
[panel release]
in that method violates Cocoa's rules of object ownership! So if you would be leaking the panel without that call, you should fix that in the method where you're creating the panel.