Question

My application performs a series of processing methods once a day or when a local notification is received to perform the series of tasks and is working as expected.

I tried adding an ActivityIndicator to a view that begins animating when a notification sent from the AppDelegate to perform the tasks is received. However all that happens is the screen darkens and none of the processing is done and the activity indicator doesn't appear. The indicator and subview that darkens the screen is used elsewhere in the app and is definitely working. I think it must be something to do with the notifications causing the app to hang and not proceed to call any of the other methods so it never completes.

This is the notification in the app delegate which is called just before the daily processing methods are called to start the activity indicator in a view controller, and the second one notifies the view controller to remove the subviews.

This method is in the AppDelegate;

- (void)GoForRankingAndSMProcessing{

    [[NSNotificationCenter defaultCenter] postNotificationName:@"ranking" object:self];

    RankingAndSMProcess *process = [RankingAndSMProcess alloc];

    [process DoRankingAndSocialMediaProcessing];

    [process release];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"rankingDone" object:self];


}

Which is picked up in another view, with the notifications setup in viewDidLoad.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(workingWhileRanking:) name:@"ranking" object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(workingFinishedRanking:) name:@"rankingDone" object:nil];

And those call these methods in that view.

-(void)workingWhileRanking:(NSNotification *) notification{

    loading = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; 

    loading.opaque = NO;
    loading.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.6f];

    indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    [indicator setHidesWhenStopped:YES];
    indicator.center = self.view.center;

    [indicator startAnimating];
    [self.view addSubview:loading];
    [self.view addSubview:indicator];

}

-(void)workingFinishedRanking:(NSNotification *) notification{

    [indicator stopAnimating];
    [indicator removeFromSuperview];
    [indicator release];
    [loading removeFromSuperview];
    [loading release];

}

The notifications must be sent as the translucent subview appears, however none of the processing methods seem to be called so the view is permanently locked out until I force close the app.

Does sending the notification change the current flow of the applications launch sequence thereby ceasing to continue executing code in a class? Or have I gone about trying to add an activity indicator to show during some behind the scenes processing the complete wrong way?

Was it helpful?

Solution

If I am not interpreting incorrectly your code:

- (void)GoForRankingAndSMProcessing{

  [[NSNotificationCenter defaultCenter] postNotificationName:@"ranking" object:self];
  RankingAndSMProcess *process = [RankingAndSMProcess alloc];
  [process DoRankingAndSocialMediaProcessing];
  [process release];
  [[NSNotificationCenter defaultCenter] postNotificationName:@"rankingDone" object:self];
}

your DoRankingAndSocialMediaProcessing is the task you would like to execute while the activity indicator is showing.

I assume that all processing happens on the same thread (UI thread), and this means that when you execute DoRankingAndSocialMediaProcessing basically your run loop (and hence, the UI) blocks and it is not updated any more. This should explain your issue.

You have several options to change this behavior, depending on what you do in DoRankingAndSocialMediaProcessing.

If you do not do anything related with the UI, it would be very easy to execute that method on a background thread by replacing the direct call to DoRankingAndSocialMediaProcessing with:

[process performSelectorInBackground:@selector(DoRankingAndSocialMediaProcessing) withObject:nil];

Of course you would then send the rankingDone notification from within DoRankingAndSocialMediaProcessing to make things work correctly.

If you can afford a background thread (i.e., you are not updating the UI from within DoRankingAndSocialMediaProcessing) this is the best option, because it will not block the UI at all.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top