0
votes

I have a navigation controller, which loads a UITableviewcontroller (DOArticleListViewController):

- (void) showList: (NSFetchedResultsController*) list title:(NSString*) title {
    DOArticleListViewController* listView = [[[self navigationController] storyboard] instantiateViewControllerWithIdentifier:@"DOArticleListViewController"];
    [listView setObjects:list];
    [listView setViewTitle:title];
    [[self navigationController] pushViewController:listView animated:YES];
}

When I tap the 'Back' button in the DOArticleListViewController the view is not released (no dealloc/viewDidUnload), and the memory usage increases every time I go back and forward.

What can be the reason, or how can I force it to release? I might have something to do with the "NSFetchedResultsController", as I only recently moved to ARC.

The declaration of the TableViewController is:

@interface DOPrototypeListViewController : DOPrototypeViewController <NSFetchedResultsControllerDelegate, UITableViewDelegate> {

    IBOutlet UITableView * _tableView;

    int _cellHeight;

@protected
    NSFetchedResultsController* _objects;   
    NSString* _cellIdentifier;

    bool _commonId;
    int _sectionItemsSkipped;
}

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSFetchedResultsController* objects;

- (NSIndexPath*)calculateObjectIndexPath:(NSIndexPath*) indexPath;
- (NSIndexPath*)calculateTableIndexPath:(NSIndexPath*) indexPath;

@end

I declared the list as strong, as if I make it weak, the NSFetchedResultsController is unloaded when I am looking for the objects when going to the subsequent detailViewController.

EDIT: I think I might have a more fundamental problem, as profiling it seems no objects are ever released. Even if the retain count is 0, the object seems to stay in memory. I moved to ARC during the summer, and did an automatic conversion. I just wonder if I have a simple fundamental flaw somewhere which causes objects to be retained and never released/dealloc.

Do objects which are instantiated in the class itself to be set to nil? e.g. do I need to set this to nil:

_mediaPlayerHelper = [[DOMediaPlayerHelper alloc] init:self];

Before ARC I would have done that, but now I have no function which is called when a view controller is removed form the view-stack (and can be removed, but this is only when going back up a level, not when gong to a detail view controller).

1
may need to be weak, yes. I think you are encountering a retain cycle issue there. Use the Instruments, with the Allocations tool to spot those - Danut Pralea
are you registering any observers or running any timers in the DOArticleListViewController? - Tobi
If I make the NSFetchedResultsController weak I lose the objects for the detailviewcontroller. I don't have any observers apart that the class is the delegate for the tableView. I could put objects on 'nil' if there is a function which is called only when the view controller is piped (not e.g. when a row is selected, so viewDidDisappear will not work) - Luuk D. Jansen
Just checked instruments. Each new instance is alive, but how can I check the reason. They have a refcount of 1, but how can I check where this is coming from? - Luuk D. Jansen
Think there dis a more fundamental problem, see edit - Luuk D. Jansen

1 Answers

0
votes

I think you can make a property and a Lazy instantiation for the

DOArticleListViewController* listView

-(DOArticleListViewController*)listView{
    if (!_listView){
        _list = [[[self navigationController] storyboard] instantiateViewControllerWithIdentifier:@"DOArticleListViewController"];
    }
    return _listView;
}

This way, you can reuse your VC.

Edited:

In response to the comment about the back button

// Set the left button for menu
UIImage *menuImage = [UIImage imageNamed:@"back_image"];

//create the button and assign the image
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
[menuButton setImage:menuImage forState:UIControlStateNormal];

[menuButton addTarget:self action:@selector(backButtonEvent:) forControlEvents:UIControlEventTouchUpInside];

//create a UIBarButtonItem with the button as a custom view
UIBarButtonItem *menuBarItem = [[UIBarButtonItem alloc] initWithCustomView:menuButton];
self.navigationItem.leftBarButtonItem = menuBarItem;

Then on the backButtonEvent method you can add all the clean actions and then make the pop for the current VC:

-(IBAction)backButtonPressed:(id)sender{
    //Clear here
    [self.navigationController popViewControllerAnimated:YES];
}