Search code examples
iosobjective-cios7

How to fully close all background work of a view controller when modally presenting another one


I have 2 view controllers, in the first one I make calculations that repeat in an endless loop.

The problem is that I want to close the method and everything related to the first method when presenting the second one. Also I am conforming to MKMapViewDelegate that is triggered everytime that user location changes, where I start a background thread work.

Now when presenting the other view controller, I want to get rid of this and break all the operations that were being executed.

I tried to set the delegates to nil, but when turn back to the first one the methods return and gives crash by saying

"Collection <__NSArrayM: 0x17f9b100> was mutated while being enumerated."

This is the function where I make calculations, the array has too many objects in it and takes about 10 sec to fully check this method.

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self makeCalculations];
    });
}

-(void)makeCalculations {
    BOOL okClicked = NO;

    for(NSDictionary *item in array) {
        NSInteger responseCode = [[item objectForKey:@"responseCode"] integerValue];

        okClicked = (responseCode > 0);

        if (okClicked) {
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"message" delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                alert.tag =10;
                [alert show];
            });
        }
    }
}

Is there any clue and can you provide me an example or suggestion?


Solution

  • Keep a counter and increment it in the loop. Then use something like:

    if(counter % 100 == 0) {
        if(self.cancelled) {
            self.cancelled = NO;
            return;
        }
    }
    

    Now, just set the cancelled BOOL when you present the new modal.

    You don't strictly need the counter, you could just check the flag each time...