Iphone 在释放变量时获取segfault(EXC\u BAD\u访问)

Iphone 在释放变量时获取segfault(EXC\u BAD\u访问),iphone,objective-c,cocoa-touch,memory-management,Iphone,Objective C,Cocoa Touch,Memory Management,好的,我知道这个错误主要来自发送一个方法调用或者试图访问一个已经被释放的变量 问题是: .h @interface TimeEntry : NSObject <NSCopying, NSCoding> { NSDate *from; NSDate *to; NSString *information; } @property (nonatomic, retain) NSDate *from; @property (nonatomic, retain) NSDate *to;

好的,我知道这个错误主要来自发送一个方法调用或者试图访问一个已经被释放的变量

问题是:

.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
这是我收到EXC\u BAD\u访问错误时的回溯

所以我向一个已经解除分配的对象发送一条消息,对吗

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

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

内存管理怎么会这么难

有什么线索吗

谢谢


Dan

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

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

-(无效)解除锁定{

}

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

你可以从

用法非常简单。看看

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

扫描构建-k-vxcodebuild

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


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


但我同意您应该在Dealoc程序结束时执行[super dealloc]。

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


更具体地说,调用
-[NSObject dealloc]
是为对象释放内存的方法。(在您的例子中,您直接扩展了NSObject,但更深层次的继承树会创建一个dealoc调用链。)一般来说,首先调用父级的
-dealoc
方法将释放从父级继承的资源。如果孩子在释放自己的资源时依赖于这些资源中的任何一种,那么你就麻烦了。由于父对象不能依赖于子对象,因此首先解除分配子资源是正确、安全的操作方式。

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

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


如前所述,在你释放其他成员后再给它打电话。

为什么会有不同?因为这是苹果告诉你的;)呵呵,这是我永远不会犯的那种讨厌的错误!!!有人能详细说明这背后的理论吗?[super dealoc]是指释放对象占用的内存,包括指向变量的指针。注意:只有-[NSObject dealoc]实际释放内存。在更深层的继承层次结构中,只有最后一个调用将解除对象本身的锁定。这个解除锁定方法中的额外的gunk是绝对不必要的。在Objective-C中,将忽略向nil发送消息-这不是带有NullPointerException的Java。我绝对推荐使用Clang静态分析器,它会捕捉到这个错误,但只要您理解这个习惯用法并知道要查找什么,通过目视检查就可以看出这一点。
-(void)dealloc{

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

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