Objective-C - 写一个简单方法的最佳实践?

3
在下面的函数中,哪个是最佳实践?
1. 发送一个自释放对象,并使调用者保留它? 2. 发送一个已分配对象,并使调用者释放它?
- (NSString*) convertDataToString :(NSData*)myData { //这只是一个例子,该方法可能不存在 NSString *str = [[NSString alloc] initWithData:myData]; return str; return [str autorelease]; }

我刚开始学习Objective C,好问题! - andy
我不确定这只是举例,但 NSString 没有 initWithData: 方法,而是有一个 initWithData:encoding: 方法。 - dreamlax
//这只是一个例子,方法可能不存在 - aryaxt
哦,哈哈,我以为那是针对 convertDataToString: 方法的。 - dreamlax
6个回答

7

跟进@Chuck的评论,-convertDataToString 不能 返回一个调用者必须释放的对象。那将违反三个魔法词。如果你的名字中没有“copy”,“alloc”或“new”,则不能指望调用者释放对象。如果你的名字中有“copy”或以“new”或“alloc”开头,则调用者必须释放对象。

Objective-C非常依赖于一致的命名规范,这些命名含义非常重要。如果你学会了这些命名规范,就不会遇到任何问题。


很好的提示和澄清了在Objective-C中约定的重要性。在我所处的托管C#世界中,约定存在,但只是一种美德(除了可能在ASP.NET MVC中)。似乎在Objective-C中,它实际上是机器中的一个齿轮。 - andy
嗨,罗布,这是否意味着如果函数名为newStringFromData,我们可以期望调用者在使用完对象后释放它。 - RK-
1
@Krishnan,对于这个方法,我们期望调用者处理一个额外的保留。调用者可能是释放对象的人(他可能被称为newStringFromSomethingElse:)。但是重点是,在我们返回它时,对象应该有一个多余的保留。 - Rob Napier
谢谢Rob,你回答了我的问题。 - RK-

3
内存管理规则指出,你的第一个例子是错误的,这是直接引用的话。这不仅仅是一种偏好,就像一些答案在这里表明的那样。调用者通常不拥有你返回的对象,所以它应该被自动释放。
规则中的具体例子如下:

这是错误的。根据所有权策略,它会导致内存泄漏。

 – (NSArray *)sprockets {

    NSArray *array = [[NSArray alloc] initWithObjects:mainSprocket,
                               auxiliarySprocket, nil];
    return array;
}

对象对新数组对象的引用仅限于sprockets方法。在方法返回后,对象失去其对新对象的引用,因此无法放弃所有权。这本身不是问题。然而,按照之前设定的命名约定,调用者没有得到拥有返回对象的指示。因此,调用者将不会放弃返回对象的所有权,导致内存泄漏。


2
大多数情况下,您应该返回一个自动释放的对象。除非您的方法名包含以下单词之一[alloc、new、copy],否则应返回自动释放的对象。

1

如果您创建、分配或复制一个对象,您需要负责释放它。基于这一点,您应该返回一个自动释放的对象。


0

我更喜欢返回自动释放对象。这意味着你不必四处寻找内存释放的位置。将内存分配和释放放在一起可以让你的生活更轻松。毕竟,你正在编写代码,为什么要让自己变得更难。


0

你不应该随意将这些单词添加到方法名称中,作为忽略内存管理规则的借口。alloccopy有特定的含义。如果您没有执行alloccopy的工作,则不应在选择器中使用它们。 - Chuck
1
“Create” 不是 Cocoa 规则的一部分,它是 Core Foundation 中的 “Create rule” 的一部分。在 Core Foundation 中,用到的词是 “copy” 和 “create”。而在 Cocoa 中,它们是 “new”,“alloc”,和 “copy”。我通常避免在 Cocoa 方法中使用 “create” 这个词以防混淆。 - Rob Napier

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