Search code examples
iosretaincount

How to handle retain count for controllers saved in AppDelegate?


MyAppDelegate is doing some background stuff and needs to refresh several views during this time, so I am saving a reference to each controller that gets created.

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
    SomethingController *currentSomethingController;
}
@property (nonatomic, retain) SomethingController *currentSomethingController;

This is done to open the controller:

- (void)openSomethingController {
    MyAppDelegate * app = [[UIApplication sharedApplication] delegate];
    app.currentSomethingController = [[SomethingController alloc] init];
    [self presentModalViewController:app.currentSomethingController animated:NO];
}

And this is called inside the controller to close it:

- (void)dismissSelf
{
    MyAppDelegate * app = [[UIApplication sharedApplication] delegate];
    [app.currentSomethingController release];
    app.currentSomethingController = nil;
[self dismissModalViewControllerAnimated:NO];
}

In MyAppDelegate the controllers is sending messages to the controller:

- (void)longRunningBackgroundTask {
    [currentSomethingController performSelectorOnMainThread:@selector(updateData) withObject:nil waitUntilDone:YES];
}

If I do Product->Analyse I get "potential leak" and "incorrect decrement" warnings. What would be the right way to do this or assuming my approach is okay, how do I tell the analysis tool to ignore those lines?


Solution

  • Even though your code seems fine, why are you doing that? It can lead to confusion to an outsider reading your code, also you should not explicitly call release on a property, you should just let the memory managment occur in the property itself, so rewrite your code like

    - (void)openSomethingController {
        MyAppDelegate * app = [[UIApplication sharedApplication] delegate];
         SomethingController *controller=[[SomethingController alloc] init];
        app.currentSomethingController = controller;
        [controller release];
        [self presentModalViewController:app.currentSomethingController animated:NO];
    }
    

    and then

    - (void)dismissSelf
    {
        MyAppDelegate * app = [[UIApplication sharedApplication] delegate];
        app.currentSomethingController = nil;
       [self dismissModalViewControllerAnimated:NO];
    }