6

我希望通过这项研究了解 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 值,以跳过已经为上一个图形上下文操作缓存的颜色转换。

我们知道在创建另一个对象时可以使用已释放对象的引用(内存地址)。所以仅仅检查引用是不够的,相同的颜色对象是有效的,但我们需要比较内容或某种哈希值。因此,我们可以为此目的使用唯一标识符值。

但是,标识符可以用于单个对象及其引用,因此仅比较 id 就足够了。但是,refs 和 ids 都被使用了。我不认为工程师忽略了这样一个简单而关键的事情。

所以,我试图找出比较 ids 和 refs 的必要性,而只比较 ids 就足够了。

它是从以前的方法遗留下来的,所以不能完全放弃吗?

4

1 回答 1

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 契约并且总是传入一个非 null c,那么一旦我们知道c== cached_c,那么我们也知道这一点cached_c != NULL,因此我们有一个有意义的值 in cached_colorID。在第二个实现中,如果c用户传入的第一个恰好有c->colorID == 0,那么我们会错误地认为我们以前见过它,然后就会出现疯狂的 hijinks。

我不知道这是否是苹果做你正在看的事情的原因......但它们似乎是可靠的可能性,不是吗?

于 2013-11-03T00:12:33.243 回答