iOS - 无法在 didSelectRowAtIndexPath 中访问 NSMutableArray?

发布于 2024-12-07 12:13:13 字数 1752 浏览 0 评论 0原文

我无法在 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”。

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

任何帮助将不胜感激。

谢谢。

I am unable to access my NSMutableArray in didSelectRowAtIndexPath although i am able to access it in cellForRowAtIndexPath.

Here is my code :-

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

}

Sometime NSLog prints some stupid output and sometime it gives me an error "EXC_BAD_ACCESS".

Please take a look and check what is wrong with my code.

Any help would be appreciated.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烂柯人 2024-12-14 12:13:13

您有一个(实际上是两个)问题,但主要问题在您的 -cellForRowAtIndexPath: 方法中:

[dict release];

去掉这一行,它应该可以正常工作。

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

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

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

您正在通过发送方式将 -retain 消息发送到您已经拥有所有权的对象引用-分配。 (当然,假设您的 @property 具有 retain setter 修饰符)

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

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

You have one (really two) issues, but the main one is in your -cellForRowAtIndexPath: method:

[dict release];

Get rid of this line and it should work just fine.

The reason why this fixes your issue is because -objectAtIndex: simply returns a pointer to the requested object in memory, therefore you do not (and should not) send the -release message to that object because the NSArray obtained ownership of the object when it was inserted. Sending -release to this object reference effectively deallocates the object in memory and now this indice in the NSArray is pointing to garbage memory. BAD BAD BAD

The other issue is that you have a memory leak here:

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

You are sending the -retain message to an object reference that you already have ownership of by way of sending -alloc. (This of course assumes that your @property has the retain setter modifier)

To fix this issue, simply send the -autorelease message to this instance:

self.drinkArray = [[[NSMutableArray alloc] initWithContentsOfFile:path] autorelease];
め七分饶幸 2024-12-14 12:13:13

不要释放对象,除非该对象是使用 alloc 创建的,或者是通过以 newcopy 开头的方法获取的,或者显式 retain< /代码>'ed。 (NARC)

在这种情况下:

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

未归还保留,因此您不拥有所有权,不应释放它。

出于同样的原因:

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

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

self.drinkArray = [NSMutableArray arrayWithContentsOfFile:path];

Don't release an object unless it was created with alloc or obtained with a method beginning with new or copy or explicitly retain'ed. (NARC)

In this case:

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

was not returned retained so you do not have ownership and should not release it.

By the same token:

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

is alloc'ed so it needs to be released or obtained with a convince method that will return an autoreleased object:

self.drinkArray = [NSMutableArray arrayWithContentsOfFile:path];
兮子 2024-12-14 12:13:13

您不应该在 cellForRowAtIndexPath[dict release]objectAtIndex 不会保留它,因此当您释放它时,它可能会被从数组中清除。

You shouldn't [dict release]in cellForRowAtIndexPath. objectAtIndex does not retain it, so it may be sweeped out of your array when you release it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文