В чем разница между NSString alloc: initWithCString и stringWithUTF8String? - PullRequest
1 голос
/ 18 апреля 2010

Я думал, что эти два метода (с точки зрения распределения памяти) эквивалентны, однако я видел «вне области видимости» и «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 голосов
/ 18 апреля 2010

Если вам нужно сохранить ссылку на объект после возврата метода, вам нужно стать владельцем объекта.Итак, если ваша переменная GUID является переменной экземпляра или какой-то глобальной, вам нужно будет взять на себя ответственность за объект.Если вы используете метод alloc / init, у вас есть право собственности на возвращенный объект, так как вы использовали alloc.Вы также можете с легкостью использовать метод stringWithUTF8String:, но вам нужно будет явно вступить во владение, отправив сообщение retain.Итак, предположим, что GUID является некоторой переменной, не относящейся к области метода:

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

(здесь можно использовать copy или retain, но copy встречается чащепри работе со строками).

Кроме того, ваш код может быть немного легче для чтения, если вы сделали что-то вроде:

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