Сбой приложения iPhone при преобразовании отформатированной строки NSString в символ UTF8 * - PullRequest
0 голосов
/ 15 октября 2010

Я хочу преобразовать NSString в const char * для доступа к базе данных sqlite.

Это работает:

NSString *queryStatementNS = @"select title from article limit 10";
const char *queryStatement = [queryStatementNS UTF8String];

Это вызывает сбой в симуляторе (без каких-либоstacktrace):

NSString *queryStatementNS = [NSString stringWithFormat:@"select title from article limit %d", 10];
const char *queryStatement = [queryStatementNS UTF8String];

Кто-нибудь может сказать мне, что метод stringWithFormat изменяется в String, чтобы выполнить преобразование в UTF8 (или в ASCII с использованием cStringUsingEncoding: NSASCIIStringEncoding) аварийно?То же самое происходит и при передаче аргумента вообще без аргумента в stringWithFormat.Может ли это быть как-то связано с управлением памятью?

1 Ответ

0 голосов
/ 15 октября 2010

Из документации:

Возвращаемая строка C автоматически освобожден так же, как возвращаемый объект быть выпущеным; Вы должны скопировать C строка, если нужно хранить ее снаружи контекста аутрелиза, в котором строка C создана.

Ваша проблема в том, что queryStatement освобождается, когда queryStatementNS освобождается, а так как queryStatementNS автоматически освобождается, вы точно не знаете, когда это произойдет. Вы можете сохранить queryStatementNS, вызвав

[queryStatementNS retain]

В какой-то момент в этой функции (не забывайте освобождать ее, когда вы хотите отказаться от владения), вы можете явно создать неавторизованную строку, чтобы иметь дело с самим собой, сказав

NSString* query = [[NSString alloc] initWithFormat:@"a string! %d", 10, nil]

(кроме этого, обратите внимание на ноль - если у вас его нет, xcode выдаст вам предупреждение об отсутствии дозорного)

или вы можете скопировать вывод [queryStatementNS UTF8String] в свой const char * queryStatement, как это было бы в простом C, с помощью strcopy или чего-либо еще.

Причина, по которой первый пример, который вы приводите, продолжает работать, заключается в том, что вы устанавливаете указатель на строковый литерал, @ "выберите заголовок из предела статьи 10". Компилятор объективного c гарантирует, что в памяти будет только один экземпляр этой строки, независимо от того, сколько раз вы ссылаетесь на нее в своем коде. Таким образом, он не подчиняется стандартным соглашениям управления памятью цели c, и ваш указатель остается действительным вне контекста автоматического освобождения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...