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:(NSIn开发者_如何学JAVAdexPath *)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 in tableView:numberOfRowsInSection:
does not retain it:
testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
filteredArrayUsingPredicate
returns an object you do not own (according to the Object Ownership Policy). Since you are accesing the ivar testList
directly, 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 = ...
and self.testList = ...
are not the same. The former accesses the ivar directly while the later goes through the accessor of the property testList
(if you have one). So, if you have a testList
retain property, it is as simple as this:
self.testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
If you do not have a testList
retain property, you can retain the object like this:
testList = [[dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]] retain];
I encourage you to use a property since they encapsulate memory management code and thus reduce boilerplate code.
精彩评论