我有一个对象,它将一个本地字符串附加到另一个,然后将其交给一个实例变量。这个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";
}
答案 0 :(得分:2)
可可内存管理不涉及范围。对象是否存在取决于所有权 - 如果另一个对象拥有它(通过使用alloc
,new
或copy
创建它,或使用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。本指南将告诉您,您已明确分配或保留的任何内容(如上所述),您必须在完成后明确发布。