loc*_*ope 6 c core-foundation opaque-pointers ios
我希望通过这项研究了解CoreFoundation CGColor对象的内部结构.我可以从免费的石英项目中找到CGColor结构的样本定义,它似乎与IOS声明相符(依赖于我的研究).
typedef struct CGColor {
CFRuntimeBase obj;
CFTypeID colorID;
CGColorSpaceRef colorSpace;
CGPatternRef pattern;
size_t numberOfComponents;
CGFloat *components;
} *CGColorRef;
Run Code Online (Sandbox Code Playgroud)
(colorID字段由free 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
Run Code Online (Sandbox Code Playgroud)
对于当前的颜色图形上下文操作,ripc_GetColor()计算当前笔触/填充颜色的一些变换,并使用此颜色的referenceID和colorID缓存这些变换.
因此,对于下一个图形上下文操作,ripc_GetColor()将先前缓存的当前引用和colorID值进行比较,以跳过已为最后一个图形上下文操作缓存的颜色转换.
我们知道在创建另一个对象时可以使用已发布对象的引用(内存地址).因此,仅检查引用将不足以使相同的颜色对象有效,但我们需要比较内容或某种哈希值.因此,我们可以为此目的使用唯一标识符值.
但是,标识符可以用于单个对象及其引用,因此仅比较ID就足够了.但是,使用了refs和id.我不认为工程师忽视了这么简单和至关重要的事情.
所以,我试图找出比较id和refs的必要性,同时只比较id就足够了.
是否遗留了以前的方法,所以不能完全放弃?
如果我理解正确的话,您会问为什么有人可能将缓存实现为
void DoSomethingWith(CGColorRef c)
{
static CGColorRef cached_c = NULL;
static CFTypeID cached_colorID;
if (c == cached_c && c->colorID == cached_colorID) ...
Run Code Online (Sandbox Code Playgroud)
而不仅仅是
void DoSomethingWith(CGColorRef c)
{
static CFTypeID cached_colorID = 0;
if (c->colorID == cached_colorID) ...
Run Code Online (Sandbox Code Playgroud)
?嗯,有两个明显的原因是
随机存取存储器不是随机存取。取消引用c可能是一个缓慢的操作(缓存未命中会浪费许多纳秒),因此如果我们可以通过预先进行廉价的指针比较来节省 90% 的纳秒时间,那么我们就这样做。
你如何初始化cached_colorID?在上面的第一个实现中,如果我们假设用户尊重 API 契约并始终传入非 null c,那么一旦我们知道c== cached_c,那么我们也知道这一点cached_c != NULL,因此我们在 中具有有意义的值cached_colorID。在第二个实现中,如果用户传入的第一个c碰巧有c->colorID == 0,那么我们会错误地认为我们以前见过它,然后就会发生疯狂的狂欢。
我不知道这是否是苹果公司做你所看到的事情的原因......但它们看起来很有可能,不是吗?