Я использую цель C в приложении C ++ для загрузки изображений на OSX. Это приложение OpenGL. Вот код, который я использую для загрузки изображения в opengl:
bool OSXSpecifics::loadPNGOSX(const char *fileName, int &outWidth, int &outHeight, GLuint *outTexture) {
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[NSString stringWithUTF8String: fileName]];
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
NSArray* imageReps = [image representations];
bool hasAlpha;
for (NSImageRep *imageRep in imageReps) {
if ([imageRep pixelsHigh] > outHeight) {
outHeight = [imageRep pixelsHigh];
}
if ([imageRep pixelsWide] > outWidth) {
outWidth = [imageRep pixelsWide];
}
}
if ([bitmap hasAlpha] == YES) {
hasAlpha = true;
} else {
hasAlpha = false;
}glGenTextures(1, outTexture);
glBindTexture(GL_TEXTURE_2D, *outTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, hasAlpha ? 4 : 3, outWidth, outHeight, 0,
hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, [bitmap bitmapData]);
[bitmap release];
[image release];
return true;
}
Благодаря приборам я обнаруживал утечку памяти каждый раз, когда вызывается эта функция. Инструменты говорит [NSImage TIFFRepresentation]
а также [NSBitmapImageRep bitmapData]
занимают огромное количество памяти.
Он не выходит из-под контроля, но каждый раз, когда эта функция называется, использование памяти поднимается на несколько сотен килобайт.
Мой опыт с целью-c ограничен, и поэтому я не знаю, как это исправить, как я думал release
будет работать нормально.
Просто чтобы вы знали, что текстура OpenGL освобождается на более позднем этапе, и я подтвердил, что она не является источником утечки памяти.
РЕДАКТИРОВАТЬ: После некоторого дальнейшего тестирования я обнаружил, что теоретически это не утечка памяти, поскольку Instruments не сообщает о «утечке памяти» как таковой. Но всякий раз, когда эта функция вызывается, использование памяти приложением увеличивается и никогда не уменьшается. Эта функция вызывается при загрузке сцен в игре, поэтому при загрузке сцены использование памяти увеличивается на несколько мегабайт. Как это могло случиться. Я уверен, что именно эта функция использует всю память.
Во-первых, код не выглядит как утечка. Я предполагаю, что NSImage выполняет некоторое безопасное внутреннее кэширование, которое гарантирует, что он может повторно использовать тот же NSImage, если вы когда-нибудь загрузите этот файл изображения во второй раз, и это, возможно, то, что вы видите. Или, может быть, это кеш файловой системы. Если память переполняется, эти кэши, вероятно, будут очищены, и освобожденная память станет доступной для вашего приложения.
Тем не менее, ваш код кажется слишком сложным. Вы создаете NSImage (который состоит из NSImageReps, один из которых, скорее всего, является NSBitmapImageRep), затем получаете его TIFFRepresentation (т.е. повторно кодируете все эти данные в TIFF, возможно, сжимаете его снова), затем создаете NSBitmapImageRep из этого (распаковывает и декодирует TIFF снова), а затем получить его bitmapData.
По крайней мере, вы, вероятно, должны создать NSData из файла и создать свой NSBitmapImageRep из этого. Это пропустит все шаги создания NSImage и TIFF.
Возможно, даже лучше было бы, если бы вы просто пошли и использовали низкоуровневую библиотеку ImageIO. Создайте CGImageRef из вашего файла, а затем передайте необработанные распакованные данные изображения в OpenGL. Я смутно помню, что может быть даже лучший способ создать текстуру OpenGL, если вы пройдете через CIImage или CoreVideo, но я могу смешивать это с обратным (текстура в CIImage).
Других решений пока нет …