Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cancelPreviousPerformRequestWithTarget is not canceling my previously delayed thread started with performSelector

I've launched a delayed thread using performSelector but the user still has the ability to hit the back button on the current view causing dealloc to be called. When this happens my thread still seems to be called which causes my app to crash because the properties that thread is trying to write to have been released. To solve this I am trying to call cancelPreviousPerformRequestsWithTarget to cancel the previous request but it doesn't seem to be working. Below are some code snippets.

- (void) viewDidLoad {
    [self performSelector:@selector(myStopUpdatingLocation) withObject:nil afterDelay:6];
}   

- (void)viewWillDisappear:(BOOL)animated {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(myStopUpdatingLocation) object:nil];
    }

Am I doing something incorrect here? The method myStopUpdatingLocation is defined in the same class that I'm calling the perform requests.

A little more background. The function that I'm trying to implement is to find a users location, search google for some locations around that location and display several annotations on the map. On viewDidLoad I start updating the location with CLLocationManager. I've build in a timeout after 6 seconds if I don't get my desired accuracy within the timeout and I'm using a performSelector to do this. What can happen is the user clicks the back button in the view and this thread will still execute even though all my properties have been released causing a crash.

Thanks in advance!

James

like image 738
jmurphy Avatar asked May 19 '10 01:05

jmurphy


2 Answers

I found my issue, it didn't have anything to do with my calls to performSelector. I found that you have to set your MKMapView and CLlocationManager's delgate to nil before releasing them. Otherwise they will continue working even though you've released the instances and they have the potential to crash your app.

Thanks for your help Noah!.

like image 177
jmurphy Avatar answered Oct 04 '22 20:10

jmurphy


I ran into a similar issue where I was unaware that I was scheduling multiple performSelector calls on different objects so the "self" was different in each case.

I'd recommend throwing in a NSLog(@"Self: %@",self); before each of your bits of code such as:

- (void) viewDidLoad {
    NSLog(@"Self: %@",self); before
    [self performSelector:@selector(myStopUpdatingLocation) withObject:nil afterDelay:6];
}   

- (void) viewWillDisappear:(BOOL)animated {
    NSLog(@"Self: %@",self); before
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(myStopUpdatingLocation) object:nil];
}

That will allow you to compare the SELF instances to ensure you are performing and releasing the selectors on the same object.

like image 36
Matt Avatar answered Oct 04 '22 20:10

Matt