2

我认为这两种方法是(内存分配方式)等效的,但是,如果我使用我认为方便的方法(在下面注释掉)并且当我切换时,我会在调试器中看到“超出范围”和“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 打印它们,它们看起来是正确的,但是,我认为没有分配新内存并复制了值。相反,内存指针被存储-超出范围-稍后引用-崩溃!

4

1 回答 1

0

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

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

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

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

GUID = p ? [[NSString stringWithUTF8String:p] copy] : @"";
于 2010-04-18T18:13:03.793 回答