gpt4 book ai didi

objective-c - NSOpenPanel 第一次访问文件夹后不显示文件

转载 作者:行者123 更新时间:2023-12-03 16:35:12 24 4
gpt4 key购买 nike

经过几天的调试,我仍然无法弄清楚为什么 NSOpenPanel(或 NSSavePanel)在第一次访问文件夹后会显示空文件列表。它看起来是随机的,即有时文件会显示(可能是因为它们被缓存),但是,正如它看起来的那样,如果第一次访问文件夹或卷则不会显示。如果用户返回并再次访问同一文件夹,所有文件都会显示。

NSOpenPanel 根据需要在主线程上以模态方式运行。还有另一个线程在运行。降低其他线程的优先级没有帮助。暂停它不是一个选择。

我怀疑 OS X 在完成检索文件后(这可能需要一段时间)会向面板(或应用程序)发送一些延迟事件。无论出于何种原因,我的 NSOpenPanel 似乎错过了它。

这是什么样的事件?如何防止它丢失?

编辑: NSOpenPanel 是由委托(delegate)对象在主线程上构建和打开的。该面板通过 [delegate PerformSelectorOnMainThread: @selector(runPanel) withObject: nil waitUntilDone: NO] 从辅助线程打开。因此,辅助线程立即继续工作并轮询委托(delegate),直到面板完成,以获取结果。

(是这样的,因为辅助线程运行模拟,需要在用户提供输入时继续)

编辑:NSOpenPanel 有一个附件 View 。

编辑:面板运行时主线程上的堆栈帧。

-[SavePanelDelegate runPanel] + 185
-[NSObject performSelector:withObject:] + 70
__NSThreadPerformPerform + 318
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
__CFRunLoopDoSources0 + 235
__CFRunLoopRun + 1022
CFRunLoopRunSpecific + 394
CFRunLoopRunInMode + 123
RunCurrentEventLoopInMode + 259
ReceiveNextEventCommon + 526
_BlockUntilNextEventMatchingListInModeWithFilter + 92
_DPSNextEvent + 1602
-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 119
-[NSApplication run] + 727
NSApplicationMain + 1165
main + 99

今天我很难重现这个问题。直到大约一个小时后,Mac 重新启动后,这种情况才再次出现。奇怪。

最佳答案

您是否从提交到主调度队列(dispatch_get_main_queue())的任务中运行打开的面板?请记住,代码路径可能是间接的。

如果是这样,那么这可能就是问题所在。

主调度队列是串行的。它一次只会运行一项任务。从此类任务中模态运行打开的面板意味着在打开的面板和当前任务的其余部分完成之前不会启动其他任务。苹果以其无限的智慧,使得在打开的面板中呈现文件的某些方面依赖于提交到主调度队列的任务。在您的情况下,这些任务直到面板关闭并且不再需要它们的结果之后才会运行。

当这种情况发生在我身上时,等待这些结果似乎有一些超时。大约一分钟后,文件出现了,但带有通用图标。

要避免此问题,您需要使用 -[NSObject PerformSelectorOnMainThread:...]CFRunLoopPerformBlock()。这两个都是基于主运行循环,它不是串行的。它是可重入的。请参阅this answer了解更多具体信息。

关于objective-c - NSOpenPanel 第一次访问文件夹后不显示文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35073030/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com