2013-10-26 127 views
6

我希望通過本研究瞭解CoreFoundation CGColor對象的內部構件。我可以從免費的石英項目中找到CGColor結構的示例定義,它似乎與IOS聲明(依賴於我的研究)相匹配。CGColor內部結構

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就足夠了。但是,使用ref和id。我不認爲工程師忽視了這樣一個簡單而關鍵的事情。

所以,我試圖找出比較ids和refs的必要性,而僅僅比較id就足夠了。

它是否從先前的方法中遺留下來,因此無法完全放棄?

+0

你看過CFTypeID嗎? https://developer.apple.com/library/mac/documentation/corefoundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/tdef/CFTypeID –

+0

抱歉,這與CFTypeID無關。 – lockedscope

+0

您正在管理實施細節。學術上有趣,但在生產代碼中通常沒有用處,除非你發現了一個特定的行爲,其性能如此糟糕以至於阻擋不了你。 – bbum

回答

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

?那麼,兩個明顯的原因是

  • Random access memory isn't random access.提領c可能是一個緩慢的操作(高速緩存未命中浪費許多納秒),因此,如果我們可以在前面加上廉價的指針比較拯救那些納秒90%的時間,讓我們做到這一點。

  • 你如何初始化cached_colorID?在上面的第一個實現中,如果我們假設用戶尊重API合同並始終傳遞非空c,那麼一旦我們知道c == cached_c,那麼我們也知道cached_c != NULL因此我們在cached_colorID中有一個有意義的值。在第二個實現中,如果用戶傳入的第一個c碰巧有c->colorID == 0,那麼我們會錯誤地認爲我們之前已經看到它,並且隨後出現了madcap hijink。

我不知道如果這些是蘋果做你看......是什麼原因,但他們似乎狀固體的可能性,不是嗎?

+0

*第一個第二個原因,它是無關的,因爲c-> colorID它從1開始。*關於第一個原因,這是相當明智的。當refs和id相等時,在第一次執行時會有一個額外的比較,但我認爲比起存儲器讀取便宜得多,所以它可以忽略不計!(我是對的嗎?)當refs不相等時,在第一個實現將只有一個比較,內存不會被讀取。但是,我不知道是否值得優化單個內存讀取,而通過變換計算將會有大量內存讀取。 – lockedscope