【问题标题】:Why does release not set the pointer to nil instead of leaving it pointing to freed memory?为什么 release 不将指针设置为 nil 而不是让它指向已释放的内存?
【发布时间】:2013-04-10 04:53:40
【问题描述】:

在下面的代码中,alert 被分配和初始化,显示,然后释放。发布前后,alert 仍然指向同一个地址。为什么系统在release之后没有设置alert指针指向nil?:

 -(void) viewDidLoad {
        UIAlertView * alert = [[UIAlertView alloc] initWithTitle: @”Hello”
                       message: @”This is an alert view”
                       delegate: self
                       cancelButtonTitle: @”OK”
                       otherButtonTitles: @”Option 1”, @”Option 2”, nil];
        [alert show];
        [alert release];
        [super viewDidLoad];
    }

【问题讨论】:

    标签: objective-c cocoa memory-management


    【解决方案1】:

    我。因为即使它是适当的,release 也不能(也不会)对调用它的对象指针做任何事情,因为就像 C 中的任何事情一样,它是按值传递的。此外,在手动引用计数下,指针永远不会隐式设置为 nil,这是 ARC 下 weak 指针的一个特性。

    二。无论如何,这都是错误的。 UIAlertView 类在显示时将自身作为子视图添加到某个视图中,因此它会被保留。因此,在您期望它被释放时,它的引用计数不为零。

    【讨论】:

    • 那么,为什么在消息发布后警报仍然存在?
    【解决方案2】:

    因为alert 指向的对象还在附近。它显示在屏幕上,因此无法从内存中删除。

    调用release 只会告诉系统“我已经完成了”。在系统(以及任何其他持有指向该对象的指针的对象)也完成处理之前,它不会显式地从内存中删除任何内容。

    【讨论】:

    • 你的意思是发布消息没有立即释放内存?
    • 不,@DungProton 和explained to you at length earlier 一样。
    • 是的,有人说立即释放消息空闲内存,但有人说不。这让我很困惑!!!
    • 在较高级别上,当您释放对它的最后所有权声明时,该对象不再有效供您使用,@DungProton。这就是您通常应该担心的一切;内存是否真正被释放是无关紧要的。在较低级别,当发送release 导致对象的引用计数变为0 时,对象将被销毁。正如 Chuck 在您的另一个问题中所指出的那样,您可以查看运行时库以了解其确切含义。
    【解决方案3】:

    这样发送的消息不可能更改非本地指针的值。你必须做一个作业:

    alert = [alert release];
    

    请注意,当您使用 ARC 编译时,weak pointers 可用,当指向的对象被销毁时,它确实使用运行时库来 nil 取出您的变量。

    其次,release 不负责销毁对象。在很多情况下,发送release 后对象实际上仍然存在,因为它还有其他所有者。

    【讨论】:

    • 你是说__weak UIAlertView * alert = [[UIAlertView alloc] initWithTitle:...@Yar?是的,这是合法的,尽管就 ARC 而言,警报视图可以立即解除分配。
    • 谢谢乔希,这很酷,我不知道。我试图想象在什么情况下(如果有的话)会有用。
    • 你说得对,auto-nils 的局部变量可能用途有限,@Yar,但如果你需要它,这种可能性是存在的!
    • 谢谢,我会寻找一个用例;)顺便说一下这个答案+1。
    • 我今天确实找到了一个用例。在您的方法中,您正在使用一个对象 (A) 并对其进行修改。 A 属于某个其他对象 (B)。如果 A 在您使用期间被解除分配(因为 B 已完成),您希望使用 nil 而不是 1)继续使用该对象(就像 ARC 通常所做的那样)和 2)获得 SIGBART。跨度>
    【解决方案4】:

    指针保存着“那个东西的地址”。 release 指向“那个东西”。它们是不同的内存位置。

    【讨论】:

      猜你喜欢
      • 2020-03-22
      • 2013-07-30
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2020-06-16
      • 1970-01-01
      相关资源
      最近更新 更多