奇怪的NSString stringByAppendingString行为

时间:2010-08-27 04:21:01

标签: iphone objective-c

我有一个对象,它将一个本地字符串附加到另一个,然后将其交给一个实例变量。这个StringObj由调用UITableViewController持有。在第一次调用时,fullCmdString正确地使用了字符串。但是,在第二次调用时,fullCmdString为null,或者充满了奇怪的数据(看起来像奇数mem位置中的数据)。我最好的猜测是stringByAppendingString返回对inStr的引用,而不是新的NSString对象,因此数据超出了范围。任何人都可以对此有所了解吗?

#import "StringObj.h"

@synthesize fullCmdString;

- (void)assemble:(NSString *)inStr {
    NSString *add = @"text added";

    //doesn't hold onto string
    fullCmdString = [NSString stringWithString:[inStr stringByAppendingString:add]];  

    //doesn't hold onto string either
    fullCmdString = [inStr stringByAppendingString:add];

    //works great
    fullCmdString = @"basic text text added";

}

3 个答案:

答案 0 :(得分:2)

可可内存管理不涉及范围。对象是否存在取决于所有权 - 如果另一个对象拥有它(通过使用allocnewcopy创建它,或使用retain声明所有权) ,它会留下来。当一个对象没有更多的所有者时,它就会消失。在您的情况下,您希望在fullCmdString中保留该NSString对象,但您没有做任何事情来声明它的所有权,因此它只是默默地消失并成为垃圾指针。

我强烈建议阅读Apple的memory management rules。这是一套非常简单的指导方针,但它会使一个工作程序和一个像这样的奇怪错误之间产生差别。

答案 1 :(得分:1)

您需要保留它:否则它将在当前作用域的末尾释放,因为stringByAppendingString返回一个自动释放的对象。

请阅读可可内存管理指南。

答案 2 :(得分:1)

// creates an autoreleased string
fullCmdString = [NSString stringWithString:[inStr stringByAppendingString:add]];  

// also creates an autoreleased string
fullCmdString = [inStr stringByAppendingString:add];

// works great, not an autoreleased string
fullCmdString = @"basic text text added";

自动释放的字符串在运行循环迭代结束时(以及自动释放池中的所有其他内容)发送release消息。如果您希望它在运行循环迭代中存活,请避免将其放入自动释放池中,或明确保留它:

// OK! Avoid the autorelease pool (at least, for fullCmdString)
fullCmdString = [[NSString alloc] initWithString:[inStr stringByAppendingString:add]]; 

// also OK! It's in the pool, but it's also been retained.
fullCmdString = [[inStr stringByAppendingString:add] retain];

// also OK
fullCmdString = @"basic text text added";

有关详细信息,请参阅Cocoa memory management rules。本指南将告诉您,您已明确分配或保留的任何内容(如上所述),您必须在完成后明确发布。