Sheet takes seconds to update


Steve Mills
 

I'm putting up a sheet from a nib to display progress while I process things. When processing is done, I change the button name and ensure the progress bar is set to max. At that point, one of the labels should be showing something like "1 of 1", but it's still stuck at "0 of 1", EVEN THOUGH I know for a fact that its stringValue has already been set to "1 of 1". If I set a breakpoint on the label's drawRect, it can take 1 to 5 seconds before drawRect will be called for the final time.

WTH's going on?

--
Steve Mills
Drummer, Mac geek


Jon Gotow
 

Has control returned to your main event loop, or are you still doing some kind of processing during the delay time? When you change the button name, etc, is that all being done from the main thread and not from a background thread?

- Jon

On Jul 10, 2019, at 11:31 AM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

I'm putting up a sheet from a nib to display progress while I process things. When processing is done, I change the button name and ensure the progress bar is set to max. At that point, one of the labels should be showing something like "1 of 1", but it's still stuck at "0 of 1", EVEN THOUGH I know for a fact that its stringValue has already been set to "1 of 1". If I set a breakpoint on the label's drawRect, it can take 1 to 5 seconds before drawRect will be called for the final time.

WTH's going on?


Steve Mills
 

On Jul 10, 2019, at 11:38:28, Jon Gotow <gotow@stclairsoft.com> wrote:

Has control returned to your main event loop, or are you still doing some kind of processing during the delay time?
Control has returned.

When you change the button name, etc, is that all being done from the main thread and not from a background thread?
Changing a UI object has to be done from the main thread, so I'm doing it from dispatch_async(dispatch_get_main_queue(), …), and I've verified that the block does get run very soon after being dispatched, so that's not what's causing the draw to be delayed. I don't think this will help, but here's the stack for the draw thread when it finally does the final draw. Note that it's NOT the main thread (which is OK here) - but why is it taking so long for this draw thread to be fired off?

#0 0x00000001000a1ed4 in -[TestLabel drawRect:] at /Users/tut/Projects/Image Chest/Image Chest/ProgressController.m:183
#1 0x00007fff4c81641e in _NSViewDrawRect ()
#2 0x00007fff4c814cac in -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inContext:shouldChangeFontReferenceColor:stopAtLayerBackedViews:] ()
#3 0x00007fff4c81463f in __46-[NSView(NSLayerKitGlue) drawLayer:inContext:]_block_invoke ()
#4 0x00007fff4c81439c in -[NSView(NSLayerKitGlue) _drawViewBackingLayer:inContext:drawingHandler:] ()
#5 0x00007fff59b18932 in CABackingStoreUpdate_ ()
#6 0x00007fff59b7a2f1 in ___ZN2CA5Layer8display_Ev_block_invoke ()
#7 0x00007fff59b17b24 in -[CALayer _display] ()
#8 0x00007fff4c81394e in _NSBackingLayerDisplay ()
#9 0x00007fff4c7f7e4f in -[_NSViewBackingLayer display] ()
#10 0x00007fff59b17055 in CA::Layer::display_if_needed(CA::Transaction*) ()
#11 0x00007fff59b0527a in CA::Context::commit_transaction(CA::Transaction*) ()
#12 0x00007fff59b048c2 in CA::Transaction::commit() ()
#13 0x00007fff59b307da in CA::Transaction::release_thread(void*) ()
#14 0x0000000100523183 in _pthread_tsd_cleanup ()
#15 0x0000000100526299 in _pthread_exit ()
#16 0x0000000100522f12 in _pthread_wqthread_exit ()
#17 0x0000000100522048 in _pthread_wqthread ()
#18 0x0000000100521e01 in start_wqthread ()

--
Steve Mills
Drummer, Mac geek


Steve Mills
 

It must have something to do with NSTextFields (or any view in general) whose value uses bindings. The text fields and the progress bar in this sheet all use bindings to set their values. If I add a test field that does NOT use bindings, and a button to set that field's value to a new value every time, I can sit here and click that button every second, and the test field's value will update as expected, but each time I click, it seems to cause the 5-second delay to restart, so it always takes around 5 seconds from the last click of the test button until the regular fields and progress bar to update to their final value.

--
Steve Mills
Drummer, Mac geek