【问题标题】:Getting a segfault (EXC_BAD_ACCESS) when deallocating variables释放变量时出现段错误(EXC_BAD_ACCESS)
【发布时间】:2010-10-08 10:50:55
【问题描述】:

好的,我了解此错误主要来自发送方法调用或尝试访问已被释放的变量。

问题来了:

.h
@interface TimeEntry : NSObject <NSCopying, NSCoding> {

NSDate *from;
NSDate *to;

NSString *information;


}

@property (nonatomic, retain) NSDate *from;
@property (nonatomic, retain) NSDate *to;

@property (nonatomic, copy) NSString *information;

@end

还有我班级的 dealloc。

-(void)dealloc{

    [super dealloc];    
    [to release];
    [from release];
    [information release];

}

这是我收到 EXC_BAD_ACCESS 错误时的回溯

所以我正在向已释放的对象发送消息,对吗?

所以我打开了 NSZombie,这停止了我的崩溃。它并没有像我希望的那样给我一些可爱的崩溃报告。相反,它只是防止程序崩溃。

在上面的 dealloc 方法中,如果我注释掉 [to release] 和 [from release] 应用程序不会崩溃。如果我只注释掉其中一个.. 它不会崩溃。在调试窗口中往返有不同的内存地址。

内存管理怎么这么难!!!

有什么线索吗?

谢谢,

【问题讨论】:

    标签: iphone objective-c cocoa-touch memory-management


    【解决方案1】:

    在释放变量之后发送 [super dealloc] 消息,而不是之前。 [super dealloc] 应该是你在 dealloc 方法中做的最后一件事。

    【讨论】:

    • 为什么会有不同?
    • 呵呵,这就是我永远不会再犯的那种恼人的错误!!!谁能详细说明这背后的理论?
    • [super dealloc] 正在释放对象占用的内存,包括指向变量的指针。
    • 注意:只有 -[NSObject dealloc] 实际上释放了内存。在更深的继承层次结构中,只有最后一次调用会释放对象本身。
    【解决方案2】:

    请注意,您可以发送 [nil release] 并且应用程序不会崩溃。 所以在发布之前检查 nil 是不必要的。

    但我同意你应该在 dealloc 过程结束时执行 [super dealloc]。

    【讨论】:

      【解决方案3】:

      您应该检查所有涉及您的属性的语句,以了解您的变量实际被释放的位置。无论如何,这是一个避免崩溃的快速解决方案,因为当且仅当它们仍然是分配的对象时,您的变量才会被释放:

      -(void)dealloc{

      if(to != nil{ 
         NSLog(@"releasing: %@", to);
         [to release];
      }
      
      if(from != nil{
         NSLog(@"releasing: %@", from);
         [from release];
      }
      
      if(information != nil){
         NSLog(@"releasing: %@", information);
         [information release];
      }
      
      [super dealloc]; 
      

      }

      此外,您可能需要下载、安装和使用 CLANG 检查器工具来了解您的代码错误的原因。这个工具(已经为 Leopard 10.5.x 构建)有时可能无法提供正确的答案,但根据我的个人经验,它从未失败过。我强烈推荐它作为您的日常开发工具之一。

      你可以从这里下载

      http://clang.llvm.org/StaticAnalysis.html

      使用起来非常简单。来看看

      http://clang.llvm.org/StaticAnalysisUsage.html#BasicUsage

      实际上,您只需使用命令构建您的 Xcode 项目

      scan-build -k -V xcodebuild

      然后,您使用将在终端窗口中显示为输出的命令检查生成的输出 HTML 文件。这些文件将为您详细解释代码中出现问题的原因。

      亲切的问候

      【讨论】:

      • 这种 dealloc 方法中的额外垃圾是绝对没有必要的。在 Objective-C 中,向 nil 发送消息会被忽略——这不是带有 NullPointerExceptions 的 Java。我绝对推荐 Clang 静态分析器,它会捕捉到这个错误,但目测很明显,只要你了解习语并知道要查找的内容。
      【解决方案4】:

      Terry 是正确的,[super dealloc] 调用必须始终是 -dealloc 中的最后一件事。

      更具体地说,调用-[NSObject dealloc] 会为对象释放内存。 (在您的情况下,您直接扩展 NSObject,但更深层次的继承树会创建一系列 dealloc 调用。)一般意义上,首先调用父级的 -dealloc 方法将释放从父级继承的资源。如果孩子在释放自己的资源时依赖于这些资源中的任何一个,那么您将陷入困境。由于父级不能依赖子级,因此首先释放子级资源是正确、安全的做事方式。

      【讨论】:

        【解决方案5】:

        当前对象的属性存储在对象中。

        当您调用 [super dealloc] 时,您是在告诉系统销毁该对象。在那次调用之后,您不能再依赖那里的属性或更正。

        如前所述,释放其他成员后调用它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-02
          • 1970-01-01
          相关资源
          最近更新 更多