Objective-C内存管理 - 返回对象的最佳实践?

13

假设我有这样一个函数:

- (NSSet *) someFunction {
    //code...
    return [[[NSSet alloc] initWithObjets:obj1, obj2, nil] autorelease];
}
当我调用这个函数时,我需要保留/释放返回值吗?我认为需要。
然而,如果我不使用autorelease,那么someFunction现在会变成这样:
- (NSSet *) someFunction {
    //code...
    return [[NSSet alloc] initWithObjets:obj1, obj2, nil];
}
在这种情况下,我假设我需要释放但不保留返回值。
我的问题是,对于这些情况,建议/最佳实践是什么?是否推荐使用某个版本的someFunction?谢谢。
3个回答

12

你应该花些时间阅读Cocoa内存管理编程指南

简而言之,如果你通过一个以'alloc'或者'new'开头或者包含'copy'的方法获取了一个引用,那么你就拥有这个引用,不需要再retain它。你需要提供它的释放方式,可以直接release或者使用autorelease。

如果你通过其他方式(比如类方法等)获取了一个引用,那么你并不拥有这个引用,所以你也不需要去释放它。如果你想保留这个引用,那么你需要retain它。

总的来说,这非常简单有效。


我相信这句话的意思是:“它是alloc,而不是init,这意味着你拥有引用”。 - cobbal
是的,您是正确的。为了后人纪念,我编辑了原始回复以反映这一点。 - Travis Jensen
5
我看到很多人参考那个编程指南。它非常非常枯燥无味,难以阅读。需要有另一个指南来代替它。 - Henley
@Hisoka:是的,它里面确实缺乏足够的性和毒品,不是吗? - Ken
@SK9 不是!没有毒品,我不开心。 - Henley

2

只有当您的方法名称以new、alloc、create、copy或类似名称开头时,才应该使用第二个示例中的代码。

否则,您需要释放(或自动释放)任何分配的对象。大多数情况下,第一个示例是正确的做法。

如果调用函数希望使值在函数作用域之外仍然存在,则应保留该值,但随后需要负责释放它。


2

嗯...

通常,我按照这个“方式”做事。

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

在返回对象之前释放它,该对象将在到达调用对象之前被释放。这会产生错误。可以使用自动释放池来避免此错误。Scott Stevenson of Theocacao最初向我介绍了这种方法。这是他和许多人使用的Obj-C 1.0首选方式。


通常情况下,方法名称的首字母不应该大写,除非它是常见缩写(例如HTTPBody,URL)。 - Denis Mikhaylov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接