Objective c 为什么在对象被释放时仍然可以调用Objective C方法?

Objective c 为什么在对象被释放时仍然可以调用Objective C方法?,objective-c,Objective C,类别定义: #import "MyClass.h" @implementation MyClass - (id)init { self = [super init]; if (self) { // Initialization code here. } return self; } - (void)dealloc { [super dealloc]; } - (void)print { NSLog(@"Hello Wor

类别定义:

#import "MyClass.h"


@implementation MyClass

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)print
{
    NSLog(@"Hello World");

}

@end
和主文件:

MyClass * m = [[MyClass alloc]init];
[m print];

[m release];

[m print];
结果:

你好,世界

你好,世界


为什么在释放对象时仍然调用第二个方法?

释放对象只是将其使用的内存标记为可用于其他用途。它不会用零或类似的东西覆盖它。在您的示例中,您没有创建任何新对象,因此没有任何东西有机会重用以前称为“m”的内存

这就是为什么释放对象并将nil指定给指针是一种常见模式,以防止意外重复使用无效对象的原因:

[m release]
m = nil;

释放一个对象只是将它使用的内存标记为可用于其他目的。它不会用零或类似的东西覆盖它。在您的示例中,您没有创建任何新对象,因此没有任何东西有机会重用以前称为“m”的内存

这就是为什么释放对象并将nil指定给指针是一种常见模式,以防止意外重复使用无效对象的原因:

[m release]
m = nil;

这是因为该对象的内存仍然存在,并且还没有被垃圾覆盖。此外,所讨论的方法不依赖于任何其他(已发布的)实例变量。简言之:这纯粹是一个成功的机会


尝试设置环境变量并再次运行该变量,以查看您是否真的“幸运”。

这是因为该对象的内存仍然存在,并且尚未被垃圾覆盖。此外,所讨论的方法不依赖于任何其他(已发布的)实例变量。简言之:这纯粹是一个成功的机会


尝试设置环境变量并再次运行该变量,以查看您是否真的有“运气”。

访问释放的内存是未定义的行为。当您调用未定义的行为时,任何事情都可能发生。这属于“任何事情”的标题,因此发生这种情况是合理的——访问错误的对象或只是崩溃也是合理的,这也是可能的结果。

访问释放的内存是未定义的行为。当您调用未定义的行为时,任何事情都可能发生。这属于“任何东西”的标题,因此发生这种情况是合理的——访问错误的对象或只是崩溃也是合理的,这也是可能的结果。

我可能会对这一有争议的模式发表评论。通过将变量设置为nil,您的应用程序在发布后使用时不会崩溃,这很好,但它会使跟踪内存管理中的错误变得更加困难,因为它不会崩溃,因此您可能不知道自己有问题。由于这些问题,我个人不使用这种模式。我虔诚地使用访问器方法,因此我可以用一只手数一数我在过去十年中遇到的内存管理错误的数量——它们很容易被追踪,因为相关代码总是很好地封装在setter方法中。:-)您是对的,很少有不依赖访问器方法的示例。但是如果您这样做,那么设置为nil也不是必需的。我在内存管理方面也有一些问题。不过,对于初学者来说,我个人认为,如果出现问题,应用程序真的崩溃比默默失败要好。但是,将变量设置为nil并使用
NSZombiesEnabled
似乎也是一个不错的选择。手动调用
-release
也几乎没有必要。我唯一一次这样做是在
-dealloc
中,通常不建议使用setter方法,以避免副作用。不过,我承认,将已发布的对象指针设置为nil有点过分-我曾经读过一篇相当有说服力的文章,认为这样做是个好主意,因此我一直在这样做,尽管在此之前从未遇到过任何重大问题。:-)我想我们都同意正确的内存管理是编写稳定程序的关键。老实说,您似乎是一名经验丰富的程序员,即使将设置设为nil out也不会真正影响您,因为您显然了解内存管理。我认为,除了这些实现细节之外,在考虑内存管理时,还需要了解对象所有权的推理和基本概念。我可能会对这个有争议的模式进行评论。通过将变量设置为nil,您的应用程序在发布后使用时不会崩溃,这很好,但它会使跟踪内存管理中的错误变得更加困难,因为它不会崩溃,因此您可能不知道自己有问题。由于这些问题,我个人不使用这种模式。我虔诚地使用访问器方法,因此我可以用一只手数一数我在过去十年中遇到的内存管理错误的数量——它们很容易被追踪,因为相关代码总是很好地封装在setter方法中。:-)您是对的,很少有不依赖访问器方法的示例。但是如果您这样做,那么设置为nil也不是必需的。我在内存管理方面也有一些问题。不过,对于初学者来说,我个人认为,如果出现问题,应用程序真的崩溃比默默失败要好。但是,将变量设置为nil并使用
NSZombiesEnabled
似乎也是一个不错的选择。手动调用
-release
也几乎没有必要。我唯一一次这样做是在
-dealloc
中,通常不建议使用setter方法,以避免副作用。不过,我承认,将已发布的对象指针设置为nil有点过分-我曾经读过一篇相当有说服力的文章,认为这样做是个好主意,因此我一直在这样做,尽管在此之前从未遇到过任何重大问题。:-)我想我们都同意正确的内存管理是编写稳定程序的关键。老实说,你似乎是一个