Ваш код на самом деле недостаточно длинный и содержит несколько мелких ошибок:
- Вы должны
CFRelease
все объекты, которыми вы владеете. Возможно, вы делаете это в другом месте, но это не очевидно из кода.
CFStringGetCStringPtr
не обещано возвращать значение. Он возвращает значение только в том случае, если строка уже хранится в нужном вам формате. Это вероятно верно в этом коде на каждой системе, на которой он, вероятно, будет работать, но это не безопасная практика CoreFoundation.
- Аналогично, небезопасно передавать результат
CFStringGetSystemEncoding
в CFStringGetCStringPtr
, так как последний требует 8-битного кодирования. Это не обещано, но ....
CFStringGetSystemEncoding
почти никогда не нужен или не уместен. Вы, вероятно, на самом деле не хотите MacRoman (что вы, вероятно, получаете, если, возможно, вы не настроены на MacJapanese). Вы, вероятно, хотите UTF8, поэтому вы должны попросить об этом.
Так вот как бы вы это сделали:
CFBundleRef mb = CFBundleGetMainBundle();
CFURLRef ur = CFBundleCopyResourceURL(mb, CFSTR("blah"), CFSTR("txt"), NULL);
CFStringRef imagePath = CFURLCopyFileSystemPath(ur, kCFURLPOSIXPathStyle);
// Now convert to a C-string
CFStringEncoding encoding = kCFStringEncodingUTF8;
CFIndex length = CFStringGetLength(imagePath);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, encoding);
char *filename = (char *)malloc(maxSize + 1); // +1 for \0
// Technically this can fail, but it really, really can't.
CFStringGetCString(imagePath, filename, maxSize, encoding);
printf( "\n we did it! .. %s \n", filename );
// Cleanup
free(filename); filename = NULL;
CFRelease(imagePath); imagePath = NULL;
CFRelease(ur); ur = NULL;
Вам могут пригодиться функции MYStringConversion . MYCFStringCopyUTF8String
возвращает вам буфер malloc (т. Е. Вам нужно free
его), содержащий строку cstring. (Они взяты из главы 10 «Программирование на iOS: раздвигая границы».)
Одна боковая нота о строковых буферах. Люди часто испытывают желание использовать буферы на основе PATH_MAX
. Имейте в виду, что macOS разрешает пути с именами намного длиннее, чем PATH_MAX
. Я не знаю каких-либо жестких ограничений на длину строки пути macOS. На практике немногие реальные пути превышают PATH_MAX
, но когда вы создаете их, интересно (а на самом деле не интересно) видеть, сколько программ ломается.
Обратите внимание, что, как правило, этот код не нужен. В большинстве проектов CoreFoundation вы просто используете ur
напрямую, и это довольно приятно по сравнению с работой с необработанными cstrings.