NSProgressIndicator needs -display after -setDoubleValue

  • Under normal circumstances; that is, in a small demo project, it is
    not necessary to send any kind of 'display' message to an
    NSProgressIndicator after updating the progress with -
    setDoubleValue.  It "just works".  But in my real project, where my
    progress indicator is programatically created and then added as a
    subview to my custom NSControl, the progress stays stuck at 0 unless
    I send it a -display after each -setDoubleValue.

    The progress is updated by a loop in a function in the main thread,
    which blocks the main thread.  Yes, I have told it to -
    useThreadedAnimation:YES.  Many times!!  But it does not help.

    Of course I don't want to leave -display in my loop, besides the fact
    that it's bad engineering, it increases the run time of a typical 2-
    second task up to about 10 seconds.  And it only works when I apply
    the heavyweight, -display.  The nicer alternatives, -setNeedsDisplay,
    and -setNeedsDisplay:YES, do not work.

    I hope someone out there might know a tidbit about
    NSProgressIndicator that might help me understand this.

    Jerry Krinock
  • On 13/10/2007, at 2:10 PM, Jerry Krinock wrote:

    > Of course I don't want to leave -display in my loop, besides the
    > fact that it's bad engineering,

    Er, forgive me if I've misunderstood, but doing work on the main
    thread doesn't sound like particularly good engineering. Surely you
    should be doing your work in a thread. That will keep the rest of
    your UI working as well as your progress bar and will be efficient.

    - Chris
  • -setUseThreadedAnimation: does exactly what it says it does. It makes
    the progress bar's animation happen in a different thread (so, for
    example the indeterminate spinner spins smoothly even when the main
    thread is blocked).

    It does not make messages you send to it run in another thread. So,
    when you call -setDoubleValue:, it sends itself a setNeedsDisplay:
    message, which will make the progress bar reflect the new value after
    the main thread stops blocking.

    Also, sending -setUseThreadedAnimation: many times does not generally
    help :)

    So, you are correct that when you block the main thread, you need to
    send  -display to get it to do its drawing immediately before it
    returns.

    There a couple solutions. First, if you can, put the loop code in a
    separate thread or process so it does not block the main thread.

    If you don't want to do that, you can always just call -
    setDoubleValue and -display every n runs through the loop so it does
    not need to redraw itself so many times. Be aware that the rest of
    the application besides the progress bar's animation will still be
    blocked, so the user may get a spinning beachball, and none of the
    controls will work.

    Adam Leonard

    On Oct 12, 2007, at 9:10 PM, Jerry Krinock wrote:

    > Under normal circumstances; that is, in a small demo project, it is
    > not necessary to send any kind of 'display' message to an
    > NSProgressIndicator after updating the progress with -
    > setDoubleValue.  It "just works".  But in my real project, where my
    > progress indicator is programatically created and then added as a
    > subview to my custom NSControl, the progress stays stuck at 0
    > unless I send it a -display after each -setDoubleValue.
    >
    > The progress is updated by a loop in a function in the main thread,
    > which blocks the main thread.  Yes, I have told it to -
    > useThreadedAnimation:YES.  Many times!!  But it does not help.
    >
    > Of course I don't want to leave -display in my loop, besides the
    > fact that it's bad engineering, it increases the run time of a
    > typical 2-second task up to about 10 seconds.  And it only works
    > when I apply the heavyweight, -display.  The nicer alternatives, -
    > setNeedsDisplay, and -setNeedsDisplay:YES, do not work.
    >
    > I hope someone out there might know a tidbit about
    > NSProgressIndicator that might help me understand this.
    >
    > Jerry Krinock
    >
  • My thanks to Chris and Adam for waking me up today.

    Yesterday, while I was making my "simple" demo, I had put the work in
    a separate thread, for another reason (so my "Cancel" button would
    work).  But I forgot the significance of that later, when I began to
    consider thread-blocking as a possible problem-causer.  Today, I
    added a switch to put the work back in the main thread, and yes
    indeed that causes the progress bar to stick.

    Conclusion:  Contrary to what I had said yesterday, in a simple demo,
    NSProgressIndicator will ^not^ show progress while the main thread is
    blocked.  And, yes, the solution is either to multithread, or -
    display or unblock periodically on a timer or counter.
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today