Re: Bindings Cocoa and new Thread (Spinning Beach Ball an new Thread)
Re: Bindings Cocoa and new Thread (Spinning Beach Ball an new Thread)
- Subject: Re: Bindings Cocoa and new Thread (Spinning Beach Ball an new Thread)
- From: "Hamish Allan" <email@hidden>
- Date: Thu, 5 Jun 2008 00:43:11 +0100
Hi Alex,
On Thu, Jun 5, 2008 at 12:10 AM, Alexander Hartner <email@hidden> wrote:
> 1.) I gathered i have to create a new NSAutoReleasePool in my "threaded"
> method. Is this correct ?
Yes.
> 2.) During execution of this I am updating the UI components from a thread
> which is not the main thread. This produces several error messages. How can
> I updated UI components. I tried using performSelectorOnMainThread, but this
> didn't work either. Not sure if this is the right approach.
See below.
> 3.) Is there an alternative way to achieve this without the beach ball
> appearing. I understand what caused it was the fact that I never exited the
> action method, at least not quickly. I would prefer an approach which did
> not require a new thread to be created.
Not really, no.
Here is some code I wrote a long time ago for doing something similar.
I had a document-based app that loaded MP3 files. For my app's
purposes, they had to be decoded to PCM data before they were useful,
so while that was happening I dropped a document-modal sheet with a
progress bar and a cancel button.
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName
error:(NSError **)outError
{
if ([typeName isEqualToString:@"MP3 Audio File"])
{
myFileData = [data retain];
[self performSelector:@selector(startDecoding:) withObject:typeName
afterDelay:0];
[self performSelector:@selector(decodeMP3Data:) withObject:data afterDelay:0];
return YES;
}
else
return [super readFromData:data ofType:typeName error:outError];
}
- (void)startDecoding:(NSString *)typeName
{
myCancelProgressFlag = FALSE;
[progressSheetInfo setStringValue:
[@"Decoding " stringByAppendingString: (NSString *)typeName]];
[progressSheetBar setUsesThreadedAnimation:YES];
[progressSheetBar setIndeterminate:YES];
[progressSheetBar startAnimation:self];
[NSApp beginSheet:progressSheet
modalForWindow:[[[self windowControllers] objectAtIndex:0] window]
modalDelegate:nil
didEndSelector:nil
contextInfo:nil];
}
- (void)endDecoding:(id)userData
{
[progressSheetBar setIndeterminate:NO];
[progressSheetBar stopAnimation:self];
[progressSheet orderOut:self];
[NSApp endSheet:progressSheet];
}
- (void)decodeMP3Data:(id)data
{
[NSThread detachNewThreadSelector: @selector(decodeMP3DataThread:)
toTarget:self withObject:data];
}
- (void)decodeMP3DataThread:(id)data
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
myPCMData = [[AudioDecoder decodeMP3Data:data progressObject:self] retain];
[self performSelectorOnMainThread: myCancelProgressFlag ?
@selector(close) : @selector(endDecoding:)
withObject:nil waitUntilDone:NO];
[pool release];
}
- (BOOL)progressSheetCheck:(float)frac
{
if (myCancelProgressFlag)
return FALSE;
if ([progressSheetBar isIndeterminate])
{
[progressSheetBar setIndeterminate:NO];
[progressSheetBar stopAnimation:self];
}
[progressSheetBar setDoubleValue:(double)frac];
return TRUE;
}
The main loop of the decoder looked something like this:
while (moreToDo)
{
float progress = 0.0;
if ([progressObject progressSheetCheck:progress])
{
// do a small amount more
progress += small_amount;
}
else
break;
}
Hope this helps,
Hamish
_______________________________________________
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