Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Mac Programming / May 2008



Tip: Looking for answers? Try searching our database.

Forcing an update of an NSTextField?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jim - 29 May 2008 13:14 GMT
I've got a code that has an NSTextField that it uses as an error line. It's
linked to an outlet variable called 'errorMessage'.

In awakeFromNib I've got a line that reads

[errorMessage setStringValue:@"Ready."];

which works as expected.

However, further into the program I've got lines that read:

[errorMessage setStringValue:@"Mounting network share..."];
[self mountNetworkShare];

'mountNetworkShare' is a routine that mounts an SMB share using
FSMountServerVolumeSync, that I guess ties the machine up for a couple of
seconds.

The problem I'm seeing is that the errorMessage field doesn't get updated
before it goes into the routine. I'm guessing it gets updates immediately
after, but as I'm setting it back to blank the effect is that the
'Mounting...' message never gets displayed.

Is there a way to force it to update the display? Or am I doing something
amusingly wrong?

Many thanks.

Jim
Signature

http://www.ursaMinorBeta.co.uk  http://twitter.com/GreyAreaUK

"Sometimes when I talk to a Windows person about using a Mac,
I feel like I'm explaining Van Halen to a horse." Merlin Mann

Jim - 29 May 2008 13:27 GMT
> [errorMessage setStringValue:@"Mounting network share..."];
> [self mountNetworkShare];
[quoted text clipped - 7 lines]
> after, but as I'm setting it back to blank the effect is that the
> 'Mounting...' message never gets displayed.

I should point out that I've also tried adding the lines:
[errorMessage setNeedsUpdate];
[errorMessage update];

before the [self mountNetworkShare] line, to no avail.

Jim
Signature

http://www.ursaMinorBeta.co.uk  http://twitter.com/GreyAreaUK

"Sometimes when I talk to a Windows person about using a Mac,
I feel like I'm explaining Van Halen to a horse." Merlin Mann

Allen Brunson - 29 May 2008 13:42 GMT
> 'mountNetworkShare' is a routine that mounts an SMB share using
> FSMountServerVolumeSync, that I guess ties the machine up for a couple of
> seconds.

that’s your problem right there.  you really can’t do something that’s going
to take a couple of seconds in your app’s main thread.  your app will appear
hung during that time, which is unacceptable.

launch a background thread and do your long-running operations there instead.
Jim - 29 May 2008 15:15 GMT
>> 'mountNetworkShare' is a routine that mounts an SMB share using
>> FSMountServerVolumeSync, that I guess ties the machine up for a couple of
[quoted text clipped - 5 lines]
>
> launch a background thread and do your long-running operations there instead.

Yes, I thought that might be the case.

Could you point me to any example code for threads? They're not something
I've had to use yet in my very limited Cocoa experience.

Many thanks.

Jim
Signature

http://www.ursaMinorBeta.co.uk  http://twitter.com/GreyAreaUK

"Sometimes when I talk to a Windows person about using a Mac,
I feel like I'm explaining Van Halen to a horse." Merlin Mann

Gregory Weston - 29 May 2008 16:03 GMT
> >> 'mountNetworkShare' is a routine that mounts an SMB share using
> >> FSMountServerVolumeSync, that I guess ties the machine up for a couple of
[quoted text clipped - 17 lines]
>
> Jim

- (void)mounterThread:(id)arg
{
 NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];
 [self mountNetworkShare];
 [errorMessage performSelectorOnMainThread:@selector(setStringValue:)
    withObject:@"" waitUntilDone:YES];
 [p release];
}

...

[errorMessage setStringValue:@"Mounting network share..."];
[NSThread detachNewThreadSelector:@selector(mounterThread:)
 toTarget:self withObject:nil];

Something like that, anyway. Just typed into MTNW without testing.

Signature

"Harry?" Ron's voice was a mere whisper. "Do you smell something ... burning?"
  - Harry Potter and the Odor of the Phoenix

Jim - 29 May 2008 16:12 GMT
> - (void)mounterThread:(id)arg
> {
[quoted text clipped - 12 lines]
>
> Something like that, anyway. Just typed into MTNW without testing.

Oh, I see. Thanks.

Does main thread execution stop until that new thread is complete? I only
ask because the commands immediately following [self mountNetworkShare]
musn't be executed until it's finished mounting (or at least trying to
mount) the share.

Is that what the 'waitUntilDone:YES' bit does?

Again, thank you.

Jim
Signature

http://www.ursaMinorBeta.co.uk  http://twitter.com/GreyAreaUK

"Sometimes when I talk to a Windows person about using a Mac,
I feel like I'm explaining Van Halen to a horse." Merlin Mann

Allen Brunson - 29 May 2008 17:10 GMT
> Does main thread execution stop until that new thread is complete?

if it did, there would be no point in launching the thread!

> I only ask because the commands immediately following
> [self mountNetworkShare] musn't be executed until it's finished
> mounting (or at least trying to mount) the share.

in that case, you’ll have to arrange for the background thread to send a
signal to your foreground thread, letting it know when it can continue doing
what it was up to.  sending an event that your app responds to would be a good
idea.

> Is that what the 'waitUntilDone:YES' bit does?

nope.
Jim - 29 May 2008 17:16 GMT
>> Does main thread execution stop until that new thread is complete?
>
> if it did, there would be no point in launching the thread!

Heh. Yes, good point.

>> I only ask because the commands immediately following
>> [self mountNetworkShare] musn't be executed until it's finished
[quoted text clipped - 4 lines]
> what it was up to.  sending an event that your app responds to would be a good
> idea.

I've started investigating [[NSThread alloc] initWith...] instead. After
I've executed [myThread start] I thought I could test to see if it's
finished with either [myThread isExecuting] or [myThread isFinished] but I'm
getting odd results from those. Probably me just being too hasty.

You've certainly given me somethinig to think about, thank you :-)

Jim
Signature

http://www.ursaMinorBeta.co.uk  http://twitter.com/GreyAreaUK

"Sometimes when I talk to a Windows person about using a Mac,
I feel like I'm explaining Van Halen to a horse." Merlin Mann

Gregory Weston - 29 May 2008 18:31 GMT
> >> Does main thread execution stop until that new thread is complete?
> >
[quoted text clipped - 17 lines]
> finished with either [myThread isExecuting] or [myThread isFinished] but I'm
> getting odd results from those. Probably me just being too hasty.

Yeah. Don't do that. Polling is bad. See my other message for ideas on
having the thread either trigger or directly perform the follow-up code
when it's time.

G

Signature

"Harry?" Ron's voice was a mere whisper. "Do you smell something ... burning?"
  - Harry Potter and the Odor of the Phoenix

Gregory Weston - 29 May 2008 18:29 GMT
> > - (void)mounterThread:(id)arg
> > {
[quoted text clipped - 16 lines]
>
> Does main thread execution stop until that new thread is complete?

No. That's the point of threads and that's why it fixes your problem
with the text field updating.

> I only
> ask because the commands immediately following [self mountNetworkShare]
> musn't be executed until it's finished mounting (or at least trying to
> mount) the share.

Ah. In that case, you have a few options. The easiest one, although it
might not be the best, is to move those lines into the thread method.

The most flexible is to perform those follow-up lines in their own
method called, say:

- (void)mountAttemptFinished:(NSNotification*)n
{
 // Do stuff.
}

Then at some point before your thread launches register that method as a
handler for a notification you've invented, and end the mounterThread:
method with code to issue that same notification. You can even pass
information along in that notification to signal whether or not the
mount succeeded (or just about anything else you might want to
communicate).

> Is that what the 'waitUntilDone:YES' bit does?

No. That prevents the worker thread from continuing until the text field
has been blanked (although not necessarily requiring that it refresh to
reflect that).

Signature

"Harry?" Ron's voice was a mere whisper. "Do you smell something ... burning?"
  - Harry Potter and the Odor of the Phoenix

Jim - 29 May 2008 18:41 GMT
> > I only
> > ask because the commands immediately following [self mountNetworkShare]
[quoted text clipped - 18 lines]
> mount succeeded (or just about anything else you might want to
> communicate).

Right-o, thanks.


> > Is that what the 'waitUntilDone:YES' bit does?
>
> No. That prevents the worker thread from continuing until the text field
> has been blanked (although not necessarily requiring that it refresh to
> reflect that).

Gotcha. Silly question in hindsight :-)

Jim
Signature

'Cloverfield' in nine words: "What is it?!" "We're gonna die!" BOOM!
Roll credits.

http://www.ursaminorbeta.co.uk   http://twitter.com/greyareauk

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.