希望通过本文的研究,了解CoreFoundation CGColor对象的内部结构。我可以从免费石英项目中找到一个CGColor结构的示例定义,它似乎与IOS声明相匹配(依赖于我的研究)。
typedef struct CGColor {
CFRuntimeBase obj;
CFTypeID colorID;
CGColorSpaceRef colorSpace;
CGPatternRef pattern;
size_t numberOfComponents;
CGFloat *components;
} *CGColorRef;(colorID字段被自由石英命名为nextID,但我认为它打算作为IOS对颜色的唯一标识符,所以它不是下一个标识符。)
持有一个全局线程安全唯一值,该值对于创建并分配给colorID成员的每个CGColor对象增加1。只有无文档化的CGColorGetIdentifier()函数才返回此值。(我猜测id值会单调增加,这可能会在设备之间转换到校准的颜色查找时提高性能,反之亦然。)
我已经检查了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值,以跳过已经为上次图形上下文操作缓存的颜色转换。
我们知道在创建另一个对象时可以使用释放对象的引用(内存地址)。因此,仅仅检查引用是不够的,同样的颜色对象是有效的,但是我们需要比较内容或某种哈希值。因此,我们可以将唯一的标识符值用于此目的。
但是,标识符可以用于单个对象及其引用,因此仅比较ids就足够了。但是,引用和ids都是使用的。我不认为工程师们忽视了这么简单和重要的事情。
所以,我试着找出比较ids和引用的必要性,而仅仅比较ids就足够了。
是否因为以前的做法而不能完全放弃呢?
发布于 2013-11-03 00:12:33
如果我理解正确的话,你会问为什么有人会将缓存实现为
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,那么我们将错误地认为我们以前见过它,随后就会出现疯狂的hijinks。我不知道这些是否是苹果做你所看到的事情的原因.但它们似乎是可靠的可能性,不是吗?
https://stackoverflow.com/questions/19607886
复制相似问题