【问题标题】:An Objective-C message was sent to a deallocated object (zombie) at address: 0xaa722d0一条 Objective-C 消息被发送到地址为 0xaa722d0 的已释放对象(僵尸)
【发布时间】:2012-02-05 17:01:23
【问题描述】:

更新: -[NSIndexPath row]:消息发送到已释放实例 0x895fe70

当我在设备上运行我的应用并分析它时说:

Objective-C 消息已发送到地址为 0xaa722d0 的已释放对象(僵尸)。

它在以下位置显示错误:

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

    int newRow = [indexPath row];
    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row]: -1;

我是 Objective C 编程的新手,两天以来一直在努力解决以下问题,我最近使用 Xcode 3.2.6 创建了一个应用程序,但两天前升级到 Xcode 4,现在在下面遇到内存释放问题代码。我研究了使用仪器并启用了僵尸并了解问题发生在哪里但无法解决它, 我请求一些指导.. 下面是我在 Xcode 4.2 中运行的代码。

#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section {
    return [list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CheckMarkCellIdentifier = @"CheckMarkCellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             CheckMarkCellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CheckMarkCellIdentifier] autorelease];
    }
    NSUInteger row = [indexPath row];
    NSUInteger oldRow = [lastIndexPath row];
    cell.textLabel.text = [list objectAtIndex:row];
    cell.accessoryType = (row == oldRow && lastIndexPath != nil) ? 
    UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;

    return cell;
}

#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    int newRow = [indexPath row];
    int oldRow = (lastIndexPath != nil) ? [lastIndexPath row]: -1;

    //----Captures the value selected in the list and shown in parent view.
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    SchneiderBMSAppDelegate *appDelegate = (SchneiderBMSAppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.priorityValue = cell.textLabel.text;

    NSLog(@"Product selected is: %@",appDelegate.priorityValue);

    if (newRow != oldRow)
    {
        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:
                                    indexPath];
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;

        UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: 
                                    lastIndexPath]; 
        oldCell.accessoryType = UITableViewCellAccessoryNone;
        lastIndexPath = indexPath;

    }

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (void)viewDidUnload {
    self.list = nil;
    self.lastIndexPath = nil;
    [super viewDidUnload];
}
- (void)dealloc {
   [list release];
    [lastIndexPath release];
    [super dealloc];
}

【问题讨论】:

  • 请在 GDB 中使用 BT 命令更新您的问题,并提供错误描述。
  • 无论问题是什么,简单地添加一个 [obj retain] 调用就可以解决它。
  • 在 Xcode 中运行分析。什么/哪里有问题?在控制台中的错误信息是什么?
  • @RRB、CodaFi 和 CocoaFu - 非常感谢您的快速回复!我刚刚发布了我遇到的错误,这会有帮助吗?
  • @CodaFi:我尝试过,非常感谢!!它有帮助!它现在可以工作了:) 我替换了 lastIndexPath = indexPath; with lastIndexPath = [indexPath 保留];

标签: iphone objective-c ios


【解决方案1】:

您似乎假设当lastIndexPath 被释放时,它将变为nil。事实并非如此。您要么需要保留对象(最好使用 setter 而不是直接设置实例变量),要么不存储对它的引用。

【讨论】:

  • 查克,成功了!! :) 太感谢了!正如建议的那样,我替换了该行: lastIndexPath = indexPath;有了这个 -> lastIndexPath = [indexPath retain];
【解决方案2】:

我有一个应用程序使用几乎相同的代码(不记得我引用了哪个教程),我在 iOS 4.3 中完成但没有发布到 App Store。当我最近恢复该应用程序并尝试在 iOS 5 中运行它时遇到了完全相同的问题。我能够通过更改行来使其工作:

lastIndexPath = indexPath;

到

self.lastIndexPath = indexPath;

然后它在 iOS 5 中运行良好。我想它通过保留对象完成了与 Chuck 推荐的相同的事情。但是为什么 iOS 5 关心而不是 iOS 4.3 呢???可能是由于 iOS 5 中的 ARC 造成的吗?

【讨论】:

  • 我自己是个新手,但我猜 iOS 5 为我们做了内存管理,而在 iOS 4.3 中,我们必须负责管理内存,这让我把那段代码放在 4.3 .只是我的两分钱..
猜你喜欢
  • 1970-01-01
  • 2013-12-02
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多