Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CGColor内部构件_Ios_C_Core Foundation_Opaque Pointers - Fatal编程技术网

Ios CGColor内部构件

Ios CGColor内部构件,ios,c,core-foundation,opaque-pointers,Ios,C,Core Foundation,Opaque Pointers,我希望通过这项研究了解CoreFoundation CGColor对象的内部结构。我可以从FreeQuartz项目中找到CGColor结构的示例定义,它似乎与IOS声明相匹配(依赖于我的研究) (free quartz将colorID字段命名为nextID,但我认为它是IOS为颜色指定的唯一标识符,因此它不是下一个标识符。) 全局线程安全的唯一值为hold,对于创建并分配给colorID成员的每个CGColor对象,该值递增1。只有未记录的CGColorGetIdentifier()函数返回此值

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

(free quartz将colorID字段命名为nextID,但我认为它是IOS为颜色指定的唯一标识符,因此它不是下一个标识符。)

全局线程安全的唯一值为hold,对于创建并分配给colorID成员的每个CGColor对象,该值递增1。只有未记录的CGColorGetIdentifier()函数返回此值。 (我有一个关于单调增加id值的猜测,它可以在设备之间转换为校准颜色查找时提高性能,反之亦然。)

我检查了CoreGraphics及其资源库。我发现只有ripc_GetColor(libRIP.A.dylib)函数调用CGColorGetIdentifier()函数

CGColorGetIdentifier的调用堆栈;(希望有助于对colorID进行推断)

对于当前颜色图形上下文操作,ripc_GetColor()计算当前笔划/填充颜色的一些转换,并使用该颜色的引用和colorID缓存这些转换

因此,对于下一个图形上下文操作,ripc_GetColor()将比较先前缓存的值和当前的引用和colorID值,以跳过已为上一个图形上下文操作缓存的颜色转换

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

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

因此,我试图找出比较id和ref的必要性,而只比较id就足够了


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

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

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%的纳秒时间,那么我们就这样做吧

  • 如何初始化
    缓存的\u colorID
    ?在上面的第一个实现中,如果我们假设用户尊重API契约并始终传入非空的
    c
    ,那么一旦我们知道
    c
    ==
    cached\u c
    ,那么我们也知道
    cached\u c!=NULL
    ,因此我们在
    缓存的\u colorID
    中有一个有意义的值。在第二个实现中,如果用户传入的第一个
    c
    恰好具有
    c->colorID==0
    ,那么我们将错误地认为我们以前见过它,于是疯狂的hijinks接踵而至


我不知道这两者是否是苹果做你所看到的事情的原因。。。但它们似乎是可靠的可能性,不是吗?

您研究过CFTypeID吗?抱歉,这与CFTypeID无关。您正在查看管道实现详细信息。学术上很有趣,但在生产代码中通常没有用处,除非你发现某个特定的行为,其性能如此糟糕以至于阻碍了你的工作。@b嗯,你的评论到底有什么意义?@BrennanVincent。创建依赖于实现细节的代码可能会被破坏。*第一个原因是,第二个原因是,它与c->colorID无关,因为它从1开始。*关于第一个原因,这是相当合理的。当refs和id都相等时,在第一个实现中会有一个额外的比较,但我假设一个比较比内存读取便宜得多,所以它可以忽略不计!。。(我说的对吗?)当ref不相等时,在第一个实现中只有一个比较,并且不会读取内存。然而,我不知道优化单个内存读取是否值得,而通过转换计算将有一系列内存读取。
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) ...