3
- (NSString *)allocString{
    NSString *str = [[NSString alloc] init];
    return str;
}

- (void)viewDidLoad{
    NSString *name = [self allocString];

    [name release]; // Can I release an object here?
}

嗨,我刚刚用 NSString 写了一个简单的例子。在我的真实程序中,我使用了一个自定义的 UIView 类,而不是 NSString。

allocString 创建一个 NSString 实例,它的保留计数为 1。没有自动释放,它只返回一个实例。

在 viewDidLoad 方法中,变量 name 只是指向 allocString 方法返回的对象,所以实例的保留计数仍然是 1。

因此,[name release] 减少了它的保留计数。

这是正确的吗?还是我必须在 allocString 方法中自动释放它?谢谢!

4

3 回答 3

6

你所做的一切都会奏效。您可以从您选择的任何范围retainrelease获取对象,只要一切都平衡(并且当任何其他对象不再需要该对象时,该对象将被释放)。

但是你所做的不是传统的。如果您想允许对象在方法的生命周期之后继续存在(以便您可以return使用它并让方法调用者拾取它),那么您应该使用autorelease.

在您的示例中,第一种方法可能不应该保留字符串的所有权。它应该释放它并让调用者拿起它。但是,当然,如果您release在方法中使用它,它将立即被释放。因此,您可以autorelease这样做。通过自动释放它,您的第一个方法是说“我不再需要这个对象并放弃我的所有权,但请在内存中保留一段时间,以便我的调用者可以在需要时保留它”

这是一个例子:

- (NSString *)createString {
    /* Create a string. This method owns it. */
    NSString *str = [[NSString alloc] init];

    /* Autorelease it. This method does not own it, but wants it to stay in memory temporarily. */
    [str autorelease]

    /* Return it. It will stay in memory till the end of the current run loop */
    return str;
}

- (void)viewDidLoad{
    NSString *name = [self createString];
    /* We now have a copy of the string. Nobody owns it. */
    /* It is due to be released at the end of the current run loop. */

    /* If we want to take ownership of it and prevent deallocation, we should retain it. */
    [name retain];
}

这种行为在整个 Cocoa API 中都有使用。当您看到返回新对象的类方法时,该对象将被自动释放。例如,当您调用时,[NSArray arrayWithObjects:@"One", @"Two", @"Three", nil]您要求 NSArray 类为您创建一个数组。arrayWithObjects:如果由于其自动释放状态而存在于方法之外。如果不这样做retain,它将在当前运行循环结束时释放。

于 2011-03-29T04:39:23.053 回答
1

如果您只是将“allocString”方法名称替换为“newString”,它就可以正常工作。目标 C 中有一个约定来处理这些方法。该约定是方法名称应以“new*”开头,并且不会引发任何内存泄漏。

于 2011-03-29T05:20:24.573 回答
0

是的,你所拥有的一切都可以正常工作。

于 2011-03-29T04:14:29.140 回答