我认为这两种方法是(内存分配方式)等价的,但是,如果我使用了我认为方便的方法(下面注释掉),我在调试器中看到“超出范围”和“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打印它们看起来是正确的,但是,我不认为已分配新内存并复制了值。而是存储指针存储 - 超出范围 - 稍后引用 - 崩溃!
答案 0 :(得分:0)
如果在方法返回后需要保持对对象的引用,则需要获取对象的所有权。因此,如果变量GUID
是实例变量或某种全局变量,则需要获取对象的所有权。如果使用alloc / init方法,则自使用alloc
以来,您拥有所返回对象的所有权。您可以轻松使用stringWithUTF8String:
方法,但您需要通过发送retain
消息明确获取所有权。因此,假设GUID
是某种非方法范围的变量:
GUID = [[NSString stringWithUTF8String:"Some UTF-8 string"] copy];
(copy
或retain
可以在这里用来取得所有权,但copy
在处理字符串时更常见。)
此外,如果您执行以下操作,您的代码可能会更容易阅读:
GUID = p ? [[NSString stringWithUTF8String:p] copy] : @"";