附加到NSString时的适当内存管理

时间:2011-11-14 23:45:57

标签: ios memory nsstring

我有一个NSString对象,我已经分配了。我想在应用程序的整个生命周期中偶尔附加到此字符串 我对如何正确处理下面示例中的内存感到困惑。感谢。

  1. 我是否需要保留每次附加的字符串,或者可以使用属于自动释放池的字符串追加,stringByAppendingString:返回?
  2. 每次我做追加时,我是否泄漏了以前分配给my_string的内存?
  3. 代码:

    NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
    NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
    my_string = [[my_string stringByAppendingString:something] retain];
    NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
    my_string = [[my_string stringByAppendingString:something_else] retain];
    [my_string release];
    

3 个答案:

答案 0 :(得分:3)

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];

不是自动释放的(因为它是使用init ...方法创建的,这是一种约定),它的retainCount为1。

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];

是自动释放的。

  

可以附加一个属于自动释放池的字符串,如   stringByAppendingString:返回

只要你期望它能存活下去。但是在你的代码中:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];
你有泄漏。您应该在重新分配之前自动释放my_string。所以最后一行应该是:

my_string = [[[my_string autorelease] stringByAppendingString:something] retain];

否则你永远丢失了指向你想释放的对象的指针。当你保留结果时,你有责任释放它,所以你也应该在最后一行之前泄漏,这应该是

my_string = [[[my_string autorelease] stringByAppendingString:something_else] retain];

答案 1 :(得分:1)

要记住的主要事情是NSString是不可变的。无论是分配,使用格式创建还是附加,您总是会返回 new 字符串对象。所以让我们打破这个:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
//String object created with "Initial string" content. Retain +1

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
//String object created with content " with something" and autoreleased.

my_string = [[my_string stringByAppendingString:something] retain];
//String object created with content "Initial string with something", autorelesed, and retained. Effective retain +1
//Assignment replaces old "Initial string" reference. "Initial string" object still has retain of +1, so it doesn't get deallocated (it leaks).

NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
//String object created with content " and something_else" and autoreleased.

my_string = [[my_string stringByAppendingString:something_else] retain];
//String object created with contents "Initial string with something and something_else", autoreleaased, and retained. Effective retain +1
//Assignment replaces old "Initial string with something" reference. "initial string with something" object still had a retain of +1, so the object leaks.

[my_string release];
//String object "Initial string with something and something_else" released. Retain -1. Object is deallocated and doesn't leak.

//...Sometime later at the end of the runloop, the autorelease pool is drained and " with something" and " with something_else" are both deallocated.

所以:

  1. 是。可以附加一个自动释放的字符串。在运行循环结束之前,不会在自动释放的对象上调用release,这至少是在此方法退出之后。

  2. 是的,每次进行追加时,您都会泄漏先前分配给my_string的对象...但不是导致泄漏的追加,而是分配。您可以将nil分配给my_string,如果您先没有my_stringrelease,则用于指向的保留对象autorelease仍会泄漏。< / p>

答案 2 :(得分:0)

在第二个作业中,您丢失了第一个stringByAppendingString来电的保留引用,因此:

  1. 可以在不调用retain的情况下附加字符串,除非您在代码中稍后需要该值。
  2. 是的,每次调用stringByAppendingString都会返回一个新的自动释放字符串。如果您暂时使用该值,请不要保留它。