I am working on a small iOS project, with a UITableView.
I made a table and put some content in it:
-(void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
NSString *fileName = [testList objectAtIndex:[indexPath row]];
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *testPath = [docsDir stringByAppendingPathComponent:fileName];
NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithContentsOfFile:testPath];
[[cell textLabel] setText:[plistDict valueForKey:@"title"]];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"indentifier"];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"identifier"];
[cell autorelease];
}
[self configureCell:cell forIndexPath:indexPath];
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDir error:nil];
testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
return [testList count];
}
This works fine. I have a table with some dummy content in it. But when i am adding this code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[testTable deselectRowAtIndexPath:indexPath animated:YES];
NSLog(@"%d",[indexPath row]);
NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);
}
The iOS simulator crashes(its not quiting, but the app doesn’t respond anymore) when i press a cell in the table. The cause of this is the next line:
NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);
When i delete this line it works perfect. This log:
NSLog(@"%d",[indexPath row]);
Returns the row number, as normal.
The strange thing is that i do exactly the same in the configureCell Function:
NSString *fileName = [testList objectAtIndex:[indexPath row]];
But that works fine.
What is going wrong here?
You need to retain
testList. The following line intableView:numberOfRowsInSection:does not retain it:filteredArrayUsingPredicatereturns an object you do not own (according to the Object Ownership Policy). Since you are accesing the ivartestListdirectly, you need to claim ownership of the object by sending it a retain message (and release it at some point in the future).Note that
testList = ...andself.testList = ...are not the same. The former accesses the ivar directly while the later goes through the accessor of the propertytestList(if you have one). So, if you have atestListretain property, it is as simple as this:If you do not have a
testListretain property, you can retain the object like this:I encourage you to use a property since they encapsulate memory management code and thus reduce boilerplate code.