Re: NSTextField not updated during large process
Re: NSTextField not updated during large process
- Subject: Re: NSTextField not updated during large process
- From: Ken Thomases <email@hidden>
- Date: Sun, 30 Sep 2012 17:51:56 -0500
On Sep 30, 2012, at 5:26 PM, Koen van der Drift wrote:
> I am downloading and parsing a large file from a database, and to keep the user informed, I have a NSTextField where I display the status. The field is bound to an NSString (progressStatus), and the controller has the following method to update it:
>
> -(void)updateStatus: (NSString *) status
> {
> NSLog(@"Status: %@", status);
> self.progressStatus = status;
> }
>
> I get all the messages displayed in the console through the NSLog, but in the second part of the whole process (the parsing), the textfield is no longer updated and keeps showing the last message from the download phase. However, the NSLog show them all, so I know that updateStatus is being called during the paring phase.
>
> Any idea what could be going on? Could the textfield not keep up with the changing of the messages?
You shouldn't be doing long-running computation or other blocking operations on the main thread. This is one of the things that goes wrong. Also, the user will see the spinning color-wheel cursor which indicates that there's something wrong with your app (which there is).
When you change the property to which the text field is bound, the text field updates some internal state and then invokes -[NSView setNeedsDisplay:] on itself, passing YES. (Or it does something similar.) This only _marks_ the text field as needing to be displayed, but does not actually display it.
Only when flow of execution returns to the main event loop does Cocoa display all windows and views that have been marked as needing it. Since your long-running operation is not allowing flow of execution to return to the event loop, this doesn't happen for the duration.
Move the long-running operation to a background thread (e.g. using -performSelectorInBackground:withObject:, or dispatch_async() to a non-main queue, or NSOperation and NSOperationQueue, etc.). However, all updates to the GUI still have to happen on the main thread. Therefore, all updates of properties to which the GUI is bound have to happen on the main thread. You can shunt those over using -performSelectorOnMainThread:..., dispatch_[a]sync to the main queue, NSOperation and +[NSOperationQueue mainQueue], etc.
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden