【问题标题】:Objective-C memory management--best practices when returning objects?Objective-C 内存管理——返回对象时的最佳实践?
【发布时间】:2009-03-28 03:13:00
【问题描述】:

假设我有这样的功能:

- (NSSet *) someFunction {
    //code...
    return [[[NSSet alloc] initWithObjets:obj1, obj2, nil] autorelease];
}

当我调用这个函数时,我需要保留/释放返回值吗?我假设我这样做了。

但是,如果我不做自动释放怎么办,所以 someFunction 现在看起来像这样:

- (NSSet *) someFunction {
    //code...
    return [[NSSet alloc] initWithObjets:obj1, obj2, nil];
}

在这种情况下,我假设我需要释放但不保留返回值。

我的问题是,对于这类情况,建议/最佳做法是什么?是否推荐使用 someFunction 的一个或另一个版本?谢谢。

【问题讨论】:

    标签: objective-c memory-management


    【解决方案1】:

    您应该花一些时间阅读Memory Management Programming Guide for Cocoa

    简而言之,如果您通过以“alloc”或“new”开头或包含“copy”的方法获取引用,则您拥有该引用并且不必保留它。您确实提供了它的发布,无论是通过直接发布还是通过使用自动发布。

    如果您以任何其他方式(通过类方法或您拥有的)获得引用,则您不拥有引用,因此您不必释放。如果要保留引用,则必须保留它。

    总的来说,它确实非常简单有效。

    【讨论】:

    • 它是 alloc,而不是 init,这意味着您拥有我相信的引用
    • 是的,你是对的。编辑原始回复以反映这一点(为了后代)。
    • 我看到很多人都在参考那个编程指南。读起来非常枯燥乏味。需要有另一个指南
    • @Hisoka:是的,里面没有足够的性或毒品,对吧?
    • @SK9 不!没有毒品,我不快乐
    【解决方案2】:

    嗯……

    通常,我遵循这种“方式”。

    + (id)MyObj {
      return [[[MyObj alloc] init] autorelease];
    }
    

    在返回之前释放对象,对象将在到达调用对象之前被释放。这将产生错误。通过使用自动释放池来避免此错误。最初是由 Theocacao 的 Scott Stevenson 介绍给我的。这是他和许多 Obj-C 1.0 的首选方式。

    【讨论】:

    • 通常情况下,方法名称的第一个字母不应使用大写字母,除非是常用缩写(例如 HTTPBody、URL)。
    【解决方案3】:

    您应该执行第二个示例中的代码的唯一原因是您的方法名称是否以 new、alloc、create、copy 或类似名称开头。

    否则,您有责任释放(或自动释放)您分配的任何对象。第一个例子是做大多数事情的正确方法。

    如果调用函数希望它在函数范围之外持续存在,则它应该保留该值,但它负责在稍后的某个时间释放它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-16
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      相关资源
      最近更新 更多