Re: threads and buttons - basic question
Re: threads and buttons - basic question
- Subject: Re: threads and buttons - basic question
- From: Dustin Voss <email@hidden>
- Date: Mon, 4 Aug 2003 14:25:58 -0700
On Friday, August 1, 2003, at 02:24 PM, Robert Palmer Jr wrote:
I have, what I believe to be, a very basic question related to
messaging and threads.
I have an app with two buttons "search" and "cancel" Only one button
should ever be enabled at any given time. Press search, it becomes
disabled and cancel becomes enabled. Press cancel and it becomes
disabled and "search" is re-enabled.
When one presses search, the "search" method is called and the search
button is disabled, cancel enabled and a new thread is created that
actually does the searching. When the searching is complete, the
thread calls a method on my controller class (the same class that
detached the thread) called "searchComplete". It is in this call that
I disable the cancel button and enable the search button.
This all works fine unless my search function fails and returns very
quickly - in this case, I can get into situations where both buttons
are enabled.
It seems that probably, the [cancelButton enable:false] message in the
"searchComplete" method is getting handled before the [cancelButton
enable:true] that is sent from the "search" search method.
Is this a correct analysis - so how do I handle it?
I tried putting the button code into another method "searchCleanup"
and calling [self performSelector:@selector(searchCleanup)
withObject:nil afterDelay:0.0]; in the "searchComplete" method. In
this case, "searchCleanup" never got called.
- (IBAction)Search:(id)sender
{
[sensors removeAllObjects];
[sensorTable reloadData];
[searchButton setEnabled:false];
[cancelButton setEnabled:true];
[progressIndicator startAnimation:self];
[m_searcher setDelegate: self];
[m_searcher search]; // this method actually detaches the NSThread
}
- (IBAction)Cancel:(id)sender
{
[m_searcher cancelSearch]; // set a flag in the class to tell the
thread's loop to exit
}
- (void)searchCleanup
{
[progressIndicator stopAnimation:self]; // this code was in the
searchComplete method
[cancelButton setEnabled:false];
[searchButton setEnabled:true];
[sensorTable reloadData];
}
- (void)searchComplete
{
[self performSelector:@selector(searchCleanup) withObject:nil
afterDelay:0.0];
}
This looks like it ought to work. I have never seen a guarantee that
during one run-loop iteration, the run-loop performs selectors in the
order they were received, but by postponing the execution of
"searchCleanup" you've accounted for that.
I'd be surprised if you made this mistake, but make sure to perform
"searchComplete" in the main thread, with
"performSelectorOnMainThread:withObject:waitUntilDone:". If you perform
that selector in the searching thread, it could be screwing up the
order. That's the only thing I can think of.
I'd like to add a UI design note: I think a "Stop" button would be more
appropriate than a "Cancel" button. "Cancel" means that changes are
disappeared. You can't really undo a search, though. "Stop" interrupts
an on-going operation. Using a file-copy as an example, "Cancel" would
stop the copying and delete the partial file, but "Stop" would stop the
copying and leave the file.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.