NSString alloc有什么区别:initWithCString和stringWithUTF8String?

时间:2010-04-18 17:36:52

标签: sqlite nsstring allocation copy-constructor

我认为这两种方法是(内存分配方式)等价的,但是,如果我使用了我认为方便的方法(下面注释掉),我在调试器中看到“超出范围”和“NSCFString”当我切换到更明确的方法时,我的代码停止了崩溃!请注意,我从sqlite3查询中获取了存储在容器中的字符串。

p = (char*) sqlite3_column_text (queryStmt, 1);
// GUID = (NSString*) [NSString stringWithUTF8String: (p!=NULL) ? p : ""];
GUID = [[NSString alloc] initWithCString:(p!=NULL) ? p : "" encoding:NSUTF8StringEncoding];

另请注意,如果我查看调试器中的值并使用NSLog打印它们看起来是正确的,但是,我不认为已分配新内存并复制了值。而是存储指针存储 - 超出范围 - 稍后引用 - 崩溃!

1 个答案:

答案 0 :(得分:0)

如果在方法返回后需要保持对对象的引用,则需要获取对象的所有权。因此,如果变量GUID是实例变量或某种全局变量,则需要获取对象的所有权。如果使用alloc / init方法,则自使用alloc以来,您拥有所返回对象的所有权。您可以轻松使用stringWithUTF8String:方法,但您需要通过发送retain消息明确获取所有权。因此,假设GUID是某种非方法范围的变量:

GUID = [[NSString stringWithUTF8String:"Some UTF-8 string"] copy];

copyretain可以在这里用来取得所有权,但copy在处理字符串时更常见。)

此外,如果您执行以下操作,您的代码可能会更容易阅读:

GUID = p ? [[NSString stringWithUTF8String:p] copy] : @"";