CGColor внутренности
Я надеюсь понять внутреннее содержание объекта CoreFoundation CGColor в этом исследовании. Я мог бы найти примерное определение структуры CGColor из проекта свободного кварца, которое, кажется, соответствует декларации IOS (опираясь на мои исследования).
typedef struct CGColor {
CFRuntimeBase obj;
CFTypeID colorID;
CGColorSpaceRef colorSpace;
CGPatternRef pattern;
size_t numberOfComponents;
CGFloat *components;
} *CGColorRef;
(Поле colorID называется свободным кварцем как nextID, но я думаю, что оно предназначено для IOS как уникальный идентификатор цвета, поэтому оно не является своего рода следующим идентификатором.)
Сохраняется уникальное глобально поточное безопасное уникальное значение, которое увеличивается на 1 для каждого объекта CGColor, созданного и назначенного элементу colorID. Только недокументированная функция CGColorGetIdentifier() возвращает это значение. (У меня есть предположение о монотонно увеличивающемся значении идентификатора, это может улучшить производительность при переводе с устройства на откалиброванный поиск цветов или наоборот.)
Я проверил CoreGraphics и его библиотеки ресурсов. Я обнаружил, что только функция ripc_GetColor (libRIP.A.dylib) вызывает функцию CGColorGetIdentifier().
Стек вызовов для CGColorGetIdentifier;(с надеждой помочь сделать выводы о colorID)
0 com.apple.CoreGraphics CGColorGetIdentifier + 0
1 libRIP.A.dylib ripc_GetColor + 112
2 libRIP.A.dylib ripc_DrawGlyphs + 1740
3 com.apple.CoreGraphics CGContextDelegateDrawGlyphs + 108
4 com.apple.CoreGraphics drawGlyphs + 284
5 com.apple.CoreGraphics CGContextShowGlyphsWithAdvances + 208
Для текущей операции контекста цветовой графики ripc_GetColor() вычисляет некоторые преобразования для текущего цвета обводки / заливки и кэширует эти преобразования со ссылкой и colorID этого цвета.
Итак, для следующей операции графического контекста ripc_GetColor() сравнивает ранее кэшированные и текущие значения ссылки и colorID, чтобы пропустить преобразования цветов, которые уже были кэшированы для последней операции графического контекста.
Мы знаем, что ссылка (адрес памяти) освобожденного объекта может быть использована при создании другого объекта. Так что простой проверки ссылки будет недостаточно, чтобы действовал тот же цветовой объект, но нам нужно сравнить содержимое или какое-нибудь хеш-значение. Таким образом, мы могли бы использовать значения уникального идентификатора для этой цели.
Однако идентификатор может использоваться для отдельного объекта и его ссылки, поэтому достаточно сравнить только идентификаторы. Но используются как ссылки, так и идентификаторы. Я не думаю, что инженеры упустили такую простую и важную вещь.
Итак, я пытаюсь выяснить необходимость сравнения идентификаторов и ссылок при сравнении только идентификаторов будет достаточно.
Осталось ли это от предыдущего подхода, и от него нельзя отказаться полностью?
1 ответ
Если я правильно понимаю, вы спрашиваете, почему кто-то может реализовать кеш как
void DoSomethingWith(CGColorRef c)
{
static CGColorRef cached_c = NULL;
static CFTypeID cached_colorID;
if (c == cached_c && c->colorID == cached_colorID) ...
вместо просто
void DoSomethingWith(CGColorRef c)
{
static CFTypeID cached_colorID = 0;
if (c->colorID == cached_colorID) ...
? Ну, две очевидные причины
Оперативная память не случайный доступ. Разыменование
c
вероятно, это медленная операция (потеря кэша тратит много наносекунд), поэтому, если мы сможем сэкономить эти наносекунды в 90% времени, добавив дешевое сравнение указателей, давайте сделаем это.Как вы инициализируете
cached_colorID
? В первой реализации выше, если мы предполагаем, что пользователь уважает контракт API и всегда передает ненулевое значениеc
тогда, когда мы знаемc
==cached_c
тогда мы также знаем, чтоcached_c != NULL
и поэтому мы имеем значимое значение вcached_colorID
, Во втором осуществлении, если первыйc
пользователь проходит, случается, имеетc->colorID == 0
, тогда мы будем неверно полагать, что мы видели это раньше, и шутки сумасбродов следуют.
Я не знаю, является ли это какой-то причиной, по которой Apple сделала то, на что вы смотрите... но они кажутся солидными возможностями, не так ли?