Должен ли быть опубликован результат CGImageGetColorSpace(изображение)?
Я масштабирую CGImageRef
, В Интернете я нашел несколько примеров кода, которые начинаются так:
CGColorSpaceRef colorspace = CGImageGetColorSpace(image); // "Get" color space
CGContextRef context = CGBitmapContextCreate(NULL, width, height,
CGImageGetBitsPerComponent(image),
CGImageGetBytesPerRow(image),
colorspace,
CGImageGetAlphaInfo(image));
CGColorSpaceRelease(colorspace); // Really?
Как вы можете видеть выше, colorspace
выпущен. Однако, когда я делаю это, мой код работает большую часть времени, но время от времени вылетает, потому что иногда этот экземпляр цветового пространства уже пропадает. Документы API говорят:
Вы несете ответственность за сохранение и освобождение цветового пространства по мере необходимости.
Значит ли это, что я должен выпустить это? Я предположил, что соглашение было, что только результаты звонков с "Create
"в названии возвращаются объекты, которые должны быть явно освобождены. Означает ли это, что примеры в Интернете просто неверны при публикации этого CGColorSpaceRef
?
5 ответов
Как говорится в документации по API, вы несете ответственность за сохранение и освобождение цветового пространства по мере необходимости. Т.е., если вам нужно, сохраните его. Если ты не сохранишь, не отпускай. Об этом подробнее здесь
Правило управления временем жизни объектов CoreFoundation и другими подобными им объектами, например, объектами CoreGraphic, заключается в том, что если вы получили объект с помощью функции, которая имеет Create
или же Copy
в его имени вам нужно использовать соответствующий метод выпуска, когда вы закончите работу с объектом.
Поскольку код в исходном вопросе показывает, что объект CoreGraphics был получен с использованием метода с Get
во имя и не Create
или же Copy
тогда вы не должны освобождать объект после его использования. Если вы выпустите релиз, вы должны ожидать аварий.
Обратите внимание, что кажется возможным получить сбой при освобождении объекта цветового пространства. Я немного покопался, но не смог установить причину аварии.
У нас есть приложение, которое считывает поля из цветового пространства каждого растрового изображения, с которым оно имеет дело, и вызывает [UIImage imageName], затем CGImageGetColorSpace и CGColorSpaceRelease. И в определенном сценарии, он будет делать это несколько раз подряд для одного и того же изображения. Недетерминированный, это иногда приводило бы к аварийному завершению со следующей ошибкой во время CGColorSpaceRelease:
Assertion failed: (!state->is_singleton), function color_space_state_dealloc, file ColorSpaces/CGColorSpace.c, line 127.
Это было на iOS5 как на ipad, так и на симе.
Я знаю, что это худший вид сообщения об ошибке, но, эй, если вы столкнетесь с той же проблемой и начнете вытягивать волосы (мы это сделали), то, возможно, это может служить подтверждением того, что вы не единственный человек, который когда-либо ударить это поведение.
Эта ошибка: "случайный сбой при выполнении тестов на соответствие WebGL" может показаться, что это та же проблема. Или этот.
Наш обходной путь состоял в том, чтобы прекратить чтение данных цветового пространства. Все еще не совсем уверен, что происходит не так. Извините, хотелось бы дать больше информации
--- Дэйв
ps, http://xkcd.com/979/, и извините за пост "здесь будут драконы".:)
Та же самая проблема случалась со мной. Я обнаружил, что в моем случае проблема заключалась в выпуске следующего ColorSpace:
CGColorSpaceRef colorSpace = CGImageGetColorSpace(pic.CGImage);
После того как я изменил эту строку на:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
все работало как и раньше, кроме ошибки:)
Да, ты должен.
Возвращенный CGColorSpaceRef
от CGImageGetColorSpace
не сохраняется, как следует из его "Get" в названии. И это ваш звонок CGColorSpaceRetain(colorSpace)
или нет.
Однако я настоятельно призываю вас сделать это (и, конечно, позже), если вы намерены сделать что-нибудь полезное с этим цветовым пространством (например, создать градиент или что-то в этом роде). Если вы этого не сделаете, вы будете приглашать себя в кошмар случайных сбоев в различных функциях CG.
Если вам нужно передать какой-либо объект CG другим функциям, всегда проверяйте, сохранен ли он. Всегда.