【问题标题】:Iphone UIAlertView throws EXC_BAD_ACCESS. - Edited, not caused by UIAlertViewIphone UIAlertView 抛出 EXC_BAD_ACCESS。 - 已编辑,不是由 UIAlertView 引起的
【发布时间】:2025-12-05 14:40:01
【问题描述】:

我不明白为什么这会给我一个 EXC_BAD_ACCESS。基本背景,我收集并处理了一些信息,然后使用模态视图让用户确认是否要继续。

我在导航栏上有一个名为 continue 的按钮,它调用我的数据准备功能。

- (void)viewDidLoad {
    //Other stuff
    UIBarButtonItem *next = [[UIBarButtonItem alloc]
                                  initWithTitle:@"Next" 
                                  style:UIBarButtonItemStyleBordered
                                  target:self
                                  action:@selector(prepData)];
    self.navigationItem.rightBarButtonItem = next;
    [next release];
    [super viewDidLoad];
}

准备数据:

-(void)prepData{
    /*
    There's a bunch of stuff going on here, if "mensaje" is not an empty NSString, there is some kind of error that wont let me go on, if not, everything in the data is fine
    */
    if(![mensaje isEqualToString:@""]){
        UIAlertView *alert = [[UIAlertView alloc] 
                              initWithTitle:nil
                              message:mensaje
                              delegate:nil 
                              cancelButtonTitle:@"Aceptar" 
                              otherButtonTitles:nil];
        [alert show];
        [alert release];
    }else{
        UIActionSheet *actionSheet = [[UIActionSheet alloc]
                                      initWithTitle:@"¿Esta seguro que desea realizar estas operaciones?" 
                                      delegate:self 
                                      cancelButtonTitle:@"Cancelar" 
                                      destructiveButtonTitle:@"Aceptar"
                                      otherButtonTitles:nil];
        [actionSheet showInView:self.view];
        [actionSheet release];
    }
}

如果我调试,我可以一直通过 prepData(),只要我按下继续,我就会得到一个 EXC_BAD_ACCESS。如果我注释掉 [actionSheet release];我没有遇到异常,但据我所知,就像警报视图一样,操作表“一直存在”直到它们显示出来。

至少我读过的所有书籍都这样说,但很可能我不理解自动发布中的某些内容。

仅供参考,弹出警报就好了。

有人知道这里发生了什么吗?

谢谢,斯特凡诺。

编辑:想通了,上面的操作表和警报视图代码很好,问题是我发布了一些后来试图自动发布的东西。

我有执行此操作的 for 循环:

for(someConditions){
    NSString *montoFormateado = [[[NSString alloc] initWithFormat:@"%.2lf",[monto doubleValue]] stringByReplacingOccurrencesOfString:@"." withString:@","];
                    [_postBuild setObject:[NSString stringWithString:montoFormateado] forKey:[NSString stringWithString:iidvar]];
                    [montoFormateado release];
}                            
postBuild = [_postBuild mutableCopy];
[_postBuild release];

现在,错误似乎在于通过使用 [NSString strintWithString:montoFormateado] 我将该字符串留待稍后自动释放,但是当我发布 _postBuild 该字符串也被释放时,我将其删除并使用setObject:montoFormateado 及其工作正常。

它的内存泄漏,但我认为这是一个不同的问题,exc_bad_access 得到了解决。

【问题讨论】:

  • 非常小的东西,但通常我认为在进行任何更改之前调用 [super viewDidLoad] 会更好,而不是在方法结束时调用。只有在调用 dealloc 时才能将 [super xxx] 放在方法的末尾。
  • 感谢小费,改变它。让我试试僵尸,看看能不能得到什么。
  • 问题很可能出在您遗漏的代码中 - 也许 mensaje 经常被释放(即释放一个自动释放的字符串)。
  • 2010-11-23 12:33:05.004 ABCDEFG[2277:207] *** -[CFString release]: message sent to deallocated instance 0xe01b2a0 我刚刚得到这个,不是很有用,我错过了关于使用僵尸的一些东西吗?
  • 很高兴你能解决它。僵尸会告诉你什么类型的物体被双重释放——这通常有助于弄清楚是什么……但不,它通常不会告诉你具体是哪个物体。如果需要,请使用 Instruments > Allocations。

标签: iphone exc-bad-access uiactionsheet


【解决方案1】:

查找此类错误的最简单方法是使用 NSZombieEnabled 环境变量。

当您在调用结束时收到 EXC_BAD_ACCESS 时,通常意味着正在自动释放某些内容,但在您释放它时它的保留计数已经为 0。

检查this post,它会多次挽救你的生命。如果这不起作用,请发表评论,我们将重新设置调试上限:)

【讨论】:

  • 接受这个是因为我使用 NSZombiesEnabled 来解决它,但是这个和 Stephens 的答案都是正确的。
【解决方案2】:

我认为你没有显示的代码中有一个版本太多(在“这里有一堆东西,如果“mensaje”不是一个空的 NSString”块)。

您的 actionSheet 代码没有问题。正如您所说,一旦不再出现在屏幕上,它就应该自行释放。但是如果你过度释放了self.view 的子视图之一,那么当自动释放池耗尽时,它可能会导致崩溃。

【讨论】:

    【解决方案3】:

    在这两种情况下,如果你要“释放”,你最好先“保留”。

    对于 UIActionSheet - 我相信传递给 showInView 的视图保留了操作表的副本。

    在 AlertView 中并非如此。

    【讨论】:

      【解决方案4】:

      也许您在使用 UIAlertView 之前就发布了它,请尝试删除发布声明并将 UIAlertView 声明为自动发布(尽管按照您的方式应该没问题)

         if(![mensaje isEqualToString:@""]){
              UIAlertView *alert = [[UIAlertView alloc] 
                                    initWithTitle:nil
                                    message:mensaje
                                    delegate:nil 
                                    cancelButtonTitle:@"Aceptar" 
                                    otherButtonTitles:nil] autorelease];
              [alert show];
      

      另一件事可能是你在某些回电之类的情况下再次释放这些家伙,你应该检查你没有这样做,就像我上面的海报所说的那样,你可以使用僵尸来解决这个问题好吧。

      【讨论】:

      • 我相信他发布的 UIAlertView 很好。我见过的Apple示例项目,使用以下步骤显示警报视图:1.分配UIAlertView,2.显示UIAlertView,3.释放UIAlertView(都在同一个范围内)。我见过的 Apple 项目示例 UIActionSheets 在调用 showInView 后也会释放操作表。
      最近更新 更多