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
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]];