iOS - 无法访问didSelectRowAtIndexPath中的NSMutableArray?

时间:2011-10-02 11:15:24

标签: iphone ios nsmutablearray exc-bad-access

我无法访问didSelectRowAtIndexPath中的NSMutableArray,但我可以在cellForRowAtIndexPath中访问它。

这是我的代码: -

- (void)viewDidLoad
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"drinks" ofType:@"plist"];
    self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
    NSLog(@"%@", self.drinkArray);
    [super viewDidLoad];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    NSLog(@"I am inside cellForRowAtIndexPath");
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
    cell.textLabel.text = [dict objectForKey:@"name"]; 
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    [dict release];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    DrinkDetails *detailViewController = [[DrinkDetails alloc] initWithNibName:@"DrinkDetails" bundle:nil];
    // ...
    // Pass the selected object to the new view controller.
    //detailViewController.drink = [self.drinkArray objectAtIndex:indexPath.row];

    NSLog(@"%@", self.drinkArray);

    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];

}

有时NSLog打印出一些愚蠢的输出,有时它会给我一个错误“EXC_BAD_ACCESS”。

请查看我的代码有什么问题。

任何帮助将不胜感激。

感谢。

3 个答案:

答案 0 :(得分:3)

您有一个(真的两个)问题,但主要问题在于您的-cellForRowAtIndexPath:方法:

[dict release];

摆脱这条线,它应该可以正常工作。

这解决了您的问题的原因是因为-objectAtIndex:只返回指向内存中所请求对象的指针,因此您不会(也不应该)发送{{1}消息到该对象,因为-release在插入对象时获得了对象的所有权。向此对象引用发送NSArray可以有效地释放内存中的对象,现在-release中的这个指向指向垃圾内存。 BAD BAD BAD

另一个问题是你在这里有内存泄漏:

NSArray

您正在通过发送self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path]; 向您已拥有所有权的对象引用发送-retain消息。 (这当然假定您的-alloc具有@property setter修饰符)

要解决此问题,只需将retain消息发送到此实例:

-autorelease

答案 1 :(得分:2)

除非使用alloc创建或使用以newcopy或明确retain编辑的方法获取对象,否则不要释放对象。 (NARC)

在这种情况下:

NSDictionary * dict = [self.drinkArray objectAtIndex:indexPath.row];

未被保留,因此您没有所有权,也不应该将其释放。

出于同样的原因:

self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

是分配的,因此需要使用会返回自动释放对象的convince方法释放或获取:

self.drinkArray = [NSMutableArray arrayWithContentsOfFile:path];

答案 2 :(得分:1)

[dict release]中不应该cellForRowAtIndexPathobjectAtIndex不保留它,因此当您释放它时,它可能会从您的阵列中消失。