You can make a difference in the Apple Support Community!

When you sign up with your Apple Account, you can provide valuable feedback to other community members by upvoting helpful replies and User Tips.

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Simple threading: performSelectorInBackground Use

Hey guys,

I saw somewhere how to animate an UIActivityIndicator while processing a time consuming stuff. I tried myself, but it keeps crashing both on simulator and device. Does anyone see what I am doing wrong?


- (IBAction)doStuff:(id)sender {
[self performSelectorInBackground:@selector(doInBackground:) withObject:nil];
}
- (void)doInBackground {
NSAutoreleasePool * pool;
pool = [[NSAutoreleasePool alloc] init];
[self doLengthyProcessing];

[self performSelectorOnMainThread:@selector(animateIndicator:) withObject:nil waitUntilDone:NO];
[pool drain];
}
- (void)animateIndicator {
[self.activityIndicator startAnimating];
}
- (void)doLengthyProcessing {
// ...
}

iMac, Mac OS X (10.5.6)

Posted on Apr 3, 2009 4:03 PM

Reply
10 replies

Apr 3, 2009 4:39 PM in response to syy

It looks like both of your @selector params should crash, since the signatures don't match the methods you intended. So I would start by removing the colons, e.g. @selector(doInBackground). Aside from that it looks like you're starting the activityIndicator where you'd want to stop it, but I didn't test your code so maybe I'm missing something there.

Apr 3, 2009 5:39 PM in response to RayNewbie

Yep, you are right, my typo. Yet the code still does not work: it crashes on device and on simulator, it starts the activity indicator only after 'doLenghtyProcessing' is done.

'-Aside from that it looks like you're starting the activityIndicator where you'd want to stop it, ... '

Hmm, my understanding is that I start 'doLenghtyProcessing' in background thread and call the main thread to animate activity indicator, right?



- (IBAction)doStuff:(id)sender {
[self performSelectorInBackground:@selector(doInBackground) withObject:nil];
}

- (void)doInBackground {
NSAutoreleasePool * pool;
pool = [[NSAutoreleasePool alloc] init];
[self doLengthyProcessing];

[self performSelectorOnMainThread:@selector(animateIndicator) withObject:nil waitUntilDone:NO];
[pool drain];
}

- (void)animateIndicator {
[self.activityIndicator startAnimating];
}

- (void)doLengthyProcessing {
// ...
}

Apr 3, 2009 6:17 PM in response to syy

Well I'm assuming \[self doLengthyProcessing\] isn't going to return for a while, which is why you wanted another thread to begin with. But that said, I'd need to setup a test bed before suggesting where to start and stop the indicator (though there's no shortage of relevant sample code). In any case, we need to find out what's crashing before worrying about the display timing. I can't promise to test anything for you this week so pending the arrival of an expert who can spot the problem with one quick glance, I'd recommend making your own test bed, stripping out everything but the code to start the thread and count to ten. Then you can begin adding things until you break it.

Apr 3, 2009 8:16 PM in response to orangekay

Thanks for all your comments guys.
So I made changes, now it seems to work in simulator, but still crashes on device.


- (IBAction)doStuff:(id)sender {
[self.indicator startAnimating]; // ok, start activity indicator before spawn
// a new thread.
[self performSelectorInBackground:@selector(doInBackground) withObject:nil];
}

- (void)doInBackground {
NSAutoreleasePool * pool;
pool = [[NSAutoreleasePool alloc] init];
[self doLengthyProcessing]; //I am putting some image processing code here
//just for the test. Since 'doInBackground' is running in background thread, any
//function calls inside 'doInBackground' should run in the background thread,
//and should return before 'doInBackground' does, am I wrong?

[self performSelectorOnMainThread:@selector(stopIndicator) withObject:nil waitUntilDone:NO];
[pool drain];
}

- (void)stopIndicator {
[self.activityIndicator stopAnimating];
}

- (void)doLengthyProcessing {
// ...
}


I found a previous discussion thread about this issue:
https://devforums.apple.com/message/24220#24220

I know I have lots to learn about concurrency/multi-threading stuff. I can't find any iPhone sample code on this: simply putting an activity indicator so users can tell device is not frozen but something is going on.

Message was edited by: syy

Apr 3, 2009 11:24 PM in response to sptrakesh

It seems like my 3G iPhone doesn't like to do number crunching in a thread spawned by 'performSelectorInBackground'. The more I strip down my 'doLengthyProcess' function, the better the device behaves.

Strange though, I called the same function ('doLengthyProcess') before in an UIImagePickerControllerDelegate method:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo

It shows an activity indicator while the function is processed, and things just work. I assume this delegate method is doing multi-threading, and my 'doLengthyProcess' function must be kosher:thread safe, etc.

Apr 6, 2009 3:25 AM in response to syy

Well, if anybody care about this problem. Here is what I did to fix the issue using Operation Object/Queue:


- (IBAction)doStuff:(id)sender {
[self.indicator startAnimating];
NSInvocationOperation *genOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doInBackground) object:nil];

MyAppDelegate *appDelegate = (MyAppDelegate *)([UIApplication sharedApplication].delegate);

[appDelegate.myQueue addOperation:genOp];
[genOp release];
}

- (void)doInBackground {
NSAutoreleasePool * pool;
pool = [[NSAutoreleasePool alloc] init];
[self doLengthyProcessing];

[self performSelectorOnMainThread:@selector(stopIndicator) withObject:nil waitUntilDone:NO];
[pool drain];
}

- (void)stopIndicator {
[self.activityIndicator stopAnimating];
}

- (void)doLengthyProcessing {
// ...
}


I don't know this is the best way but it seems to work.

Simple threading: performSelectorInBackground Use

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.