我希望通过这项研究了解CoreFoundation CGColor对象的内部。我可以从免费的 quartz 项目中找到CGColor结构的示例定义,该定义似乎与IOS声明相匹配(根据我的研究)。

typedef struct CGColor {
        CFRuntimeBase obj;

        CFTypeID colorID;
        CGColorSpaceRef colorSpace;
        CGPatternRef pattern;
        size_t numberOfComponents;
        CGFloat *components;
} *CGColorRef;

(colorID字段由免费的 quartz 命名为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()比较先前缓存的和当前的reference和colorID值,以跳过为上一个图形上下文操作已经缓存的颜色转换。

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

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

因此,我尝试找出比较ID和refs的必要性,而仅比较IDs就足够了。

它是从以前的方法中遗留下来的,因此不能完全丢弃吗?

最佳答案

如果我理解正确,您是在问为什么有人可能将缓存实现为

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) ...

?好吧,两个明显的原因是
  • Random access memory isn't random access.取消引用c可能是一个缓慢的操作(缓存未命中会浪费许多纳秒),因此,如果我们可以通过便宜的指针比较来节省90%的纳秒时间,那就开始吧。
  • 如何初始化cached_colorID?在上面的第一个实现中,如果我们假设用户遵守API契约(Contract)并始终传递非null的c,则一旦我们知道c == cached_c,那么我们也知道cached_c != NULL,因此我们在cached_colorID中具有有意义的值。在第二种实现中,如果用户传入的第一个c恰好具有c->colorID == 0,那么我们将错误地认为我们之前已经看过它,随后便出现了madcap hijinks。

  • 我不知道这两个原因是否是Apple做到了您要看的东西的原因...但是它们似乎是可靠的可能性,不是吗?

    关于ios - CGColor内部,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19607886/

    10-09 02:34