Search code examples
iphoneobjective-ciosios5

Object Released too soon with iOS 5 ARC


I'm a newbie on objective-c programming language and I've noticed a strange behavior in memory management. With iOS 5 ARC is enabled by default but an object is released too soon, maybe someone can give me some advice.

This is the case:

I've a Dao object which retrieve data from a SQLite database using Core Data PersistenceStore. This Dao implements a method "getAllAuthors"

In my viewController in viewWillAppear method I load this data and data are loaded but when I populate a tableView the objects are (null).

I post some code:

@synthesize authors;
@synthesize authorsTable;
@synthesize dao;

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"author in viewDidLoad: %@", [[authors objectAtIndex:0] name]);
}

- (void)viewDidUnload {
    [super viewDidUnload];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    dao = [[CrossoverDao alloc] init];
    authors = [NSArray arrayWithArray:[dao getAllAuthors]];
    [authorsTable reloadData];
    NSLog(@"author in viewWillAppear: %@", [[authors objectAtIndex:0] name]);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [authorsTable reloadData];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"author in viewWillDisappear: %@", [[authors objectAtIndex:0] name]);
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"author in viewDidDisappear: %@", [[authors objectAtIndex:0] name]);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:    (UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

#pragma mark -
#pragma mark UITableViewDataSource datasource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath     *)indexPath {
    NSLog(@"[AuthorsViewController::cellForRowAtIndexPath] Constructing row at indexPath: %d",     indexPath.row);
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView 
                             dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        if(indexPath.section == 0)
            cell = [[UITableViewCell alloc]     initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
        else
            cell = [[UITableViewCell alloc]     initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.text = [[authors objectAtIndex:indexPath.row] name];
    cell.detailTextLabel.text = [[authors objectAtIndex:indexPath.row] bio];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section {
    NSLog(@"author in numberOfRowsInSection: %@", [[authors objectAtIndex:0] name]);
    return [authors count];
}

In cellForRowAtIndexPath the author is null. Any clue?

Thanks in advance


Solution

  • You should ensure that you set your properties using the synthesized accessors so that ARC knows that you want to keep them if they are strong (here it just inserted releases at the end of your viewWillAppear method). Change

    dao = [[CrossoverDao alloc] init];
    authors = [NSArray arrayWithArray:[dao getAllAuthors]];
    

    to

    self.dao = [[CrossoverDao alloc] init];
    self.authors = [NSArray arrayWithArray:[dao getAllAuthors]];