NSPathControl Causing Disk I/O Reading NSURL Resource Values On the Main Thread

Sort of a continuation of - https://developer.apple.com/forums/thread/813641

I've made a great effort to get NSURL -getResourceValue:forKey: calls etc off the main thread. Great progress. So now I'm working with a file on a really slow network volume I discovered a little hang and luckily enough I'm attached to the debugger so I paused that thing. I see where I'm at. It is:

NSPathControl's setURL:. It goes a little something like this:

in realpath$DARWIN_EXTSN ()

+fileSystemRealPath ()

+[FSNode(SandboxChecks) canAccessURL:withAuditToken:operation:] ()

+FSNode(SandboxChecks) canReadFromSandboxWithAuditToken:] ()

LaunchServices::URLPropertyProvider::prepareLocalizedNameValue ()

LaunchServices::URLPropertyProvider::prepareValues () prepareValuesForBitmap ()

FSURLCopyResourcePropertiesForKeysInternal ()

CFURLCopyResourcePropertiesForKeys ()

-[NSURL resourceValuesForKeys:error:] () in function signature specialization <Arg[1] = Dead> of Foundation._NSFileManagerBridge.displayName(atPath: Swift.String) -> Swift.String () in displayName ()

-[NSPathCell _autoUpdateCellContents] ()

-[NSPathCell setURL:] ()

Could maybe, NSPathControl get the display name etc. asynchronously? and maybe just stick raw path components in as a placeholder while it is reading async? Or something like that? If I can preload the resource keys it needs I would but once the NSURL asks on the main main thread I think it will just dump the cache out, per the run loop rules.

FB22294400

Could maybe, NSPathControl get the display name etc. asynchronously? and maybe just stick raw path components in as a placeholder while it is reading async? Or something like that?

Not really. That is, you might be able to subclass the control to get the behavior you want; however, I think the work involved would be fairly similar making your own control using our view components.

However...

If I can preload the resource keys it needs, I would, but once the NSURL asks on the main thread, I think it will just dump the cache out, per the run loop rules.

...you should be able to do this. NSURL does work this way (the run loop reset), but CFURL does NOT, so if you create a CFURLRef and preload it with the expected keys, it should do exactly what you need. Keep in mind that using CFURLRef for this is easier than you think— you don't actually need to convert from NSURL to CFURLRef; you just have to create the CFURLRef and then cast that CFURLRef into an NSURL. What you'll then end up with is an object that works fine as an NSURL but should have different caching behavior (since it's actually a CFURLRef). I'd probably use the CF API to fetch the required resources, but that's more out of an abundance of caution than because it's required.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Not really. That is, you might be able to subclass the control to get the behavior you want; however, I think the work involved would be fairly similar making your own control using our view components.

True. Yea it isn't too much work. Just needed to fetch the titles and the icon images in the background.

but CFURL does NOT,

I briefly thought about this though I wasn't sure how path control grabs the icons (through the url or something else like NSWorkspace) and I wanted to have that in the bg too.

Under normal conditions this isn't a big deal but dealing with a url on a slow network it can cause a little hitch, as I discovered!

NSPathControl Causing Disk I/O Reading NSURL Resource Values On the Main Thread
 
 
Q