3. CALayer 的代理和繪制

屏幕為什么會(huì)卡頓? 通常的我們熟悉的 drawRect: 方法,但是是什么時(shí)候調(diào)用的? 一個(gè)視圖是怎么樣在手機(jī)上顯示的? CALayer是怎么樣異步繪制? 帶著這些問題我們往下研究一下聂喇。

一: 視圖顯示

我們的視圖要想顯示在手機(jī)上暴匠,一般的需要通過CPU 和 GPU的處理,IOS屏幕的Vsyn信號(hào)的頻率是 1/60s,如果在這個(gè)時(shí)間內(nèi)還沒處理完,就會(huì)導(dǎo)致卡頓房维。

CPU渲染

image
  1. Layout: UI的Frame 計(jì)算
  2. 繪制: display階段,就是我們通過 Core Graphics來處理
  3. prepare: 如果是圖片的話沼瘫,需要進(jìn)行圖片解碼
  4. commit: 其實(shí)通過CoreAnimation提交給OpenGL,layer

GPU渲染

頂點(diǎn)著色咙俩、圖元裝配耿戚、片段著色湿故、片段處理 大概有個(gè)概念就行,我們主要討論FrameBuffer光柵化, 因?yàn)檫@涉及到離屏幕渲染 膜蛔、在屏幕渲染 坛猪、圖層混合合成

image
  • 在屏幕渲染 :表示在當(dāng)前的屏幕的緩存區(qū)內(nèi)渲染
  • 離屏幕渲染 :其實(shí)是在未預(yù)合成之前 不能在當(dāng)前屏幕渲染,需要放到當(dāng)前屏幕緩沖區(qū)外緩存皂股;我們可以通過開啟 Color Offscreen-Rendered Yellow 來檢查墅茉。主要是以下事件會(huì)導(dǎo)致離屏幕渲染:
     1. 設(shè)置圓角 + maskToBounds
     2. 圖層蒙版
     3. 陰影、漸變呜呐、不透明就斤、抗鋸齒(edge antialiasing)
     4. 光柵化: 
        (1.) 將圖轉(zhuǎn)換為 用柵格 組成的bitmap,每個(gè)格柵對應(yīng)幀緩沖的一個(gè)位置,這樣下次如果圖片沒有改變的話就可以直接復(fù)用蘑辑。
        (2.) 通過 “Color Hits Green and Misses Red”,來檢測洋机,綠色表示復(fù)用。
        (3.) 通常的我們會(huì)選擇 有多種層級的視圖并且含有透明通道洋魂, 可以進(jìn)行 光柵化,減少渲染時(shí)間
        (4.) 開啟: layer.shouldRasterize=YES & layer.contentsScale = [UIScreen mainScreen].scale
        
    

二: 繪制

IOS 通過UIView 來處理事件的傳遞問題绷旗,而繪制是通過CALayer來處理,其實(shí)就是很好的單一模式,同時(shí)的calayer.delegate = uiview忧设。在UIView 和 CALayer 的原碼方面我主要是參考Chameleon

1. CALayer 繪制過程

CALayer 通過 -(void)display 方法來進(jìn)行繪制刁标,這個(gè)時(shí)候會(huì)判斷delegate 是否實(shí)現(xiàn)了-(void)displayLayer:,如果實(shí)現(xiàn)了就進(jìn)行自定義繪制流程,反之則進(jìn)行 CALayer系統(tǒng)的繪制來自定義創(chuàng)建buffer 和 context址晕,創(chuàng)建好了膀懈,就判斷是否有代理實(shí)現(xiàn)了 drawLayer:inContext: 這樣可以把context 傳遞過去。

image

2. 異步繪制

就是通過 實(shí)現(xiàn) CAlayer代理的 -(void)displayLayer:谨垃,自己創(chuàng)建 buffer 和 context 启搂,繪制結(jié)束后脾拆,通過commit的時(shí)候進(jìn)行提交給GPU處理围来。

一般的有下面
// 創(chuàng)建 context 和 進(jìn)行繪制枷踏, 一般是放在子線程處理
CGBitmapContextCreate()
....CoreGraphic API 
id content =  CGBitmapContextCreateImage()

//進(jìn)行提交操作荣月,需要回到主線程進(jìn)行處理
[CALayer setContents:] 

3. Chameleon源碼,查看UIView

通過查看Chameleon, UIView實(shí)現(xiàn)了 drawLayer:inContext: 方法.可以清楚的看到 通過創(chuàng)建好的

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
            UIGraphicsPushContext(ctx);
            UIGraphicsPushContext(ctx);
            const CGRect bounds = CGContextGetClipBoundingBox(ctx);
            [self.backgroundColor setFill]; //背景色的設(shè)置
            CGContextFillRect(ctx,bounds);
            
            '[self drawRect:bounds];'  //添加自定義的繪制
            
            CGContextRestoreGState(ctx);
            UIGraphicsPopContext();
    }        
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市实抡,隨后出現(xiàn)的幾起案子阁簸,更是在濱河造成了極大的恐慌畔柔,老刑警劉巖纷责,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捍掺,死亡現(xiàn)場離奇詭異,居然都是意外死亡再膳,警方通過查閱死者的電腦和手機(jī)挺勿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喂柒,“玉大人不瓶,你說我怎么就攤上這事禾嫉。” “怎么了蚊丐?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵熙参,是天一觀的道長。 經(jīng)常有香客問我麦备,道長尊惰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任泥兰,我火速辦了婚禮,結(jié)果婚禮上题禀,老公的妹妹穿的比我還像新娘鞋诗。我一直安慰自己,他們只是感情好迈嘹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布削彬。 她就那樣靜靜地躺著,像睡著了一般秀仲。 火紅的嫁衣襯著肌膚如雪融痛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天神僵,我揣著相機(jī)與錄音雁刷,去河邊找鬼。 笑死保礼,一個(gè)胖子當(dāng)著我的面吹牛沛励,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炮障,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼目派,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胁赢?” 一聲冷哼從身側(cè)響起企蹭,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎智末,沒想到半個(gè)月后谅摄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吹害,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年螟凭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片它呀。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡螺男,死狀恐怖棒厘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情下隧,我是刑警寧澤奢人,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站淆院,受9級特大地震影響何乎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜土辩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一支救、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拷淘,春花似錦各墨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至结洼,卻和暖如春黎做,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背松忍。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工蒸殿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挽铁。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓伟桅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親叽掘。 傳聞我的和親對象是個(gè)殘疾皇子楣铁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容