【问题标题】:Why is release often called shortly after a local var is used instead of just autoreleasing为什么经常在使用本地 var 而不是自动发布后不久调用 release
【发布时间】:2011-08-17 23:56:03
【问题描述】:

我经常看到类似下面的东西:

UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(refreshPropertyList:)];          
  self.navigationItem.rightBarButtonItem = anotherButton;
  [anotherButton release];

特别是在使用本地变量的地方,在这种情况下是“另一个按钮”,然后再发布。这与分配它时自动释放它并确保在方法结束之前使用它完全一样吗?即:

UIBarButtonItem *anotherButton = [[[UIBarButtonItem alloc] initWithTitle:@"Show" style:UIBarButtonItemStylePlain target:self action:@selector(refreshPropertyList:)] autorelease];          
  self.navigationItem.rightBarButtonItem = anotherButton;

我问是因为我看到它在很多时候都是以第一种方式完成的,但是(对我来说)感觉不太容易出错(对我来说)直接自动释放它。这只是个人风格的问题,还是这两种方法有区别,除了一种在完成后有条不紊地释放对象,另一种注意一开始就声明它被释放,以免意外算了,各有千秋。

【问题讨论】:

    标签: objective-c release autorelease


    【解决方案1】:

    来自Tuning for Performance and Responsiveness 中的明智地分配内存表7-2分配内存的技巧:

    提示

    减少使用 autoreleased 对象。

    采取的行动

    使用自动释放释放的对象 方法留在记忆中,直到你 明确地消耗电流 自动释放池或直到下一个 围绕事件循环的时间。 无论何时 可能,避免使用自动释放 方法,当您可以改为使用 释放内存的方法 立即被物体占据。如果 你必须创造适量的 自动释放对象,创建本地 自动释放池并排空它 定期回收内存 下一个事件之前的那些对象 循环。

    【讨论】:

    • 但是,在这种情况下,立即释放对象不太可能回收内存,因为它可能已被导航项保留。鉴于此,它实际上只是归结为风格问题。 (是的,我认识到一个人不应该依赖于其他对象可能会或可能不会对一大块内存做什么。另一方面,也不应该编写一个内存限制如此之大以至于推迟释放单个对象的应用程序按钮几微秒可能会有所作为。)
    • 谢谢,这是我在 RTFM 时错过的一个细节。然而,对于绝大多数 iOS 应用程序来说,在下一个事件循环之前担心你的自动释放池的大小似乎是无稽之谈。如果您正在运行某种具有数百或数千次迭代的算法,并且您将对象放在自动释放池中,我可以看到这非常重要,但是当我们谈论在分配池中放置 5-10 个对象时新视图,在用户选择下一个操作之前,这会影响多久?
    • 引用段落中的关键词是“中等数字”。
    【解决方案2】:

    当您自动释放某些东西时,您会将其添加到一组对象中,这些对象将在将来的某个时间点释放。这意味着这些对象仍然存在。由于 iOS 提供的内存量有限,因此建议您尽可能使用释放而不是自动释放。您不希望您的程序因内存不足而崩溃,因为您有很多自动释放的对象。

    【讨论】:

      【解决方案3】:

      很好的问题。通过自动释放,您正在延迟对象的自动释放。当您需要从方法中返回某些内容时,这一切都很好,而且是预期的行为,但是将该对象保留在内存中的时间超过必要的时间可能会对您的应用产生影响。

      通过在完成后释放它,您此时正在释放资源,并且内存可以在运行时被另一个对象使用。在 Cocos2D 中,自动释放几乎所有内容是标准做法,而且一切似乎都可以正常工作,但它仍然让我感到不快,而且我一般不会这样做。

      【讨论】:

        【解决方案4】:

        他们完成同样的事情。有些人认为您应该尽可能避免使用自动释放,因此强烈希望尽快发布。昨天刚刚讨论过here

        在您引用的代码中,两者之间的差异确实很小。即使anotherButton 被释放,它也不太可能被释放,因为分配给self.navigationItem.rightBarButtonItem 可能会导致anotherButton 被保留。

        IMO 和在这种情况下,尽快调用 release 的最佳理由是,通过释放 anotherButton,您明确记录了您已完成使用它的事实。此外,如果您在发布后使​​用anotherButton,静态分析器会提示您。这两个事实可以帮助您避免错误,并使您的代码更易于理解。

        在这种情况下支持自动释放的论点是它可能更容易阅读。我认为 Apple 为我们提供所有这些便捷方法(例如 +stringWithFormat)是有原因的:它们让您可以通过一种方法而不是三种方法创建和使用所需的字符串。

        【讨论】:

          猜你喜欢
          • 2020-01-16
          • 2010-10-22
          • 2018-08-31
          • 2016-06-04
          • 1970-01-01
          • 2018-01-06
          • 1970-01-01
          • 2019-03-30
          • 2019-01-20
          相关资源
          最近更新 更多