在嘗試異步繪制前犬绒,我去了解了這些iOS渲染知識(shí)

前言

  • 這一塊主要為了面試講項(xiàng)目準(zhǔn)備,盡量理論與實(shí)踐相結(jié)合吧挂签,能把搜到的資料都實(shí)現(xiàn)最好
  • 目前主要是為tableView的優(yōu)化進(jìn)行研究疤祭,把涉及到的異步繪制【圖層問題】,網(wǎng)絡(luò)請(qǐng)求中的cell中空間高度緩存這些就用到最好

FPS

  • FPS是圖像領(lǐng)域中的定義饵婆,是指畫面每秒傳輸幀數(shù)勺馆,通俗來講就是指動(dòng)畫或視頻的畫面數(shù)。FPS是測(cè)量用于保存侨核、顯示動(dòng)態(tài)視頻的信息數(shù)量草穆。每秒鐘幀數(shù)越多,所顯示的動(dòng)作就會(huì)越流暢搓译。通常悲柱,要避免動(dòng)作不流暢的最低是30。
  • iPhone的FPS為60些己,也就是說它在一秒鐘內(nèi)會(huì)刷新60次豌鸡,每次間隔大概16.7ms,也就是說我們的iPhone每次有16.7ms的時(shí)間來處理事件
  • 而如果在這個(gè)時(shí)間內(nèi)沒能成功刷新段标,就會(huì)直接丟棄這一幀涯冠,下一次一起整上去【也就是說,不會(huì)原地刷新】
  • 這樣子幀的丟失反映到用到用戶體驗(yàn)上就 = APP卡頓了

CPU

  • 中央處理器(CPU逼庞,central processing unit)作為計(jì)算機(jī)系統(tǒng)的運(yùn)算和控制核心蛇更,是信息處理、程序運(yùn)行的最終執(zhí)行單元
  • 放在我們的iOS中赛糟,可以理解為CPU負(fù)責(zé)軟件的操作械荷,對(duì)象創(chuàng)建、對(duì)象調(diào)整虑灰、對(duì)象銷毀吨瞎、布局計(jì)算、文本計(jì)算穆咐、文本渲染颤诀、圖片解碼字旭、圖像的繪制等操作是放在CPU上執(zhí)行的

GPU

  • 圖形處理器(英語:Graphics Processing Unit,縮寫:GPU)崖叫,又稱顯示核心遗淳、視覺處理器、顯示芯片心傀,是一種專門在個(gè)人電腦屈暗、工作站、游戲機(jī)和一些移動(dòng)設(shè)備(如平板電腦脂男、智能手機(jī)等)上做圖像和圖形相關(guān)運(yùn)算工作的微處理器养叛。
  • 放在iOS中,GPU處理的是硬件層面的事宰翅,紋理的渲染弃甥、視圖混合、離屏渲染都是在GPU上執(zhí)行的

位圖

  • 位圖是由稱作像素(圖片元素)的單個(gè)點(diǎn)組成的汁讼。這些點(diǎn)可以進(jìn)行不同的排列和染色以構(gòu)成圖樣淆攻。當(dāng)放大位圖時(shí),可以看見賴以構(gòu)成整個(gè)圖像的無數(shù)單個(gè)方塊嘿架。擴(kuò)大位圖尺寸的效果是增大單個(gè)像素瓶珊,從而使線條和形狀顯得參差不齊。然而耸彪,如果從稍遠(yuǎn)的位置觀看它艰毒,位圖圖像的顏色和形狀又顯得是連續(xù)的。用數(shù)碼相機(jī)拍攝的照片搜囱、掃描儀掃描的圖片以及計(jì)算機(jī)截屏圖等都屬于位圖丑瞧。位圖的特點(diǎn)是可以表現(xiàn)色彩的變化和顏色的細(xì)微過渡,產(chǎn)生逼真的效果蜀肘,缺點(diǎn)是在保存時(shí)需要記錄每一個(gè)像素的位置和顏色值绊汹,占用較大的存儲(chǔ)空間。常用的位圖處理軟件有Photoshop(同時(shí)也包含矢量功能)扮宠、Painter和Windows系統(tǒng)自帶的畫圖工具等西乖,Adobe Illustrator則是矢量圖軟件

像素點(diǎn)如何出現(xiàn)在屏幕上

  • 先來看一張全部流程圖:
pixels-software-stack
  • 這張圖從從右到左就是軟件到硬件,從App到硬件屏幕上出現(xiàn)界面的全過程
  • 這里再介紹下前面沒介紹的模塊

渲染參與者

  • GPU Driver:GPU驅(qū)動(dòng)軟件坛增,直接和 GPU 交流的代碼塊
  • OpenGL:提供了 2D 和 3D 圖形渲染的 API获雕,高GPU的能力,并實(shí)現(xiàn)硬件加速渲染收捣,是第一個(gè)和圖形硬件(GPU)交流的標(biāo)準(zhǔn)化方式
  • Core Graphics:Quartz 2D的一個(gè)高級(jí)繪圖引擎届案,常用與iOS,tvOS罢艾,macOS的圖形繪制應(yīng)用開發(fā)楣颠。Core Graphics是對(duì)底層C語言的一個(gè)簡單封裝尽纽,其中提供大量的低層次,輕量級(jí)的2D渲染API童漩。前綴為CG弄贿,比如常見的CGPath,CGColor
  • Core Animation:是蘋果提供的一套基于繪圖的動(dòng)畫框架矫膨,但不止是動(dòng)畫差凹,他同樣是繪圖的根本【因?yàn)槠淝熬Y是CA,CALayer有多重要就不用多說了吧】
6379271-f8367726caa19e8a
  • 從圖中可以看出侧馅,最底層是圖形硬件(GPU)危尿;上層是OpenGL和CoreGraphics,提供一些接口來訪問GPU施禾;再上層的CoreAnimation在此基礎(chǔ)上封裝了一套動(dòng)畫的API。最上面的UIKit屬于應(yīng)用層搁胆,處理與用戶的交互
  • Core Image:iOS處理圖像的框架弥搞,主要用處可以給圖片添加濾鏡效果和圖像識(shí)別功能

we are A!R渠旁!G攀例!B!

  • 這里講下對(duì)于像素需要知道的知識(shí):
  • 屏幕上的像素是由紅顾腊,綠粤铭,藍(lán)三種顏色組件構(gòu)成的。因此杂靶,位圖數(shù)據(jù)有時(shí)也被叫做 RGB 數(shù)據(jù)
  • ARGB:32bits-per-pixel(bpp), 8bits-per-componet(bpc),透明度會(huì)首先被乘以到像素值上【也就是說對(duì)于透明度的處理我們直接就是百分比乘到RGB值里面】
  A   R   G   B   A   R   G   B   A   R   G   B  
| pixel 0       | pixel 1       | pixel 2   
  0   1   2   3   4   5   6   7   8   9   10  11 ...
  
這個(gè)格式經(jīng)常被叫做 ARGB梆惯。每個(gè)像素占用 4 字節(jié)(32bpp),每一個(gè)顏色組件是1字節(jié)(8bpc).每個(gè)像素有一個(gè) alpha 值,這個(gè)值總是最先得到的(在RGB值之前)吗垮,最終紅垛吗、綠、藍(lán)的值都會(huì)被預(yù)先乘以 alpha 的值

如果我們有一個(gè)橙色烁登,他們各自的 8bpc 就像這樣: 240,99,24.一個(gè)完全不透明的橙色像素?fù)碛械?ARGB 值為: 255怯屉,240,99饵沧,24锨络,它在內(nèi)存中的布局就像上面圖示那樣。如果我們有一個(gè)相同顏色的像素狼牺,但是 alpha 值為 33%羡儿,那么他的像素值便是:84,80是钥,33失受,8.
  • xRGB:像素并沒有任何 alpha 值(他們都被假定為100%不透明)讶泰,但是內(nèi)存布局是一樣的,這樣子將會(huì)節(jié)約內(nèi)存【拂到?痪署??:這種格式容易被現(xiàn)代的 CPU 和繪圖算法消化兄旬,因?yàn)槊恳粋€(gè)獨(dú)立的像素都對(duì)齊到 32-bit 的邊界】
  x   R   G   B   x   R   G   B   x   R   G   B  
| pixel 0       | pixel 1       | pixel 2   
  0   1   2   3   4   5   6   7   8   9   10  11 ...
  • xRGB即沒有alpha通道的圖片狼犯,它無法選擇透明度,雖然我們我們說有alpha通道的像素點(diǎn)其實(shí)就是將alpha預(yù)乘到了RGB里面领铐,但這不意味著alpha沒用悯森,在合成像素點(diǎn)的時(shí)候我們依然需要用alpha值計(jì)算混合后的值,所以對(duì)于這種圖片就是無法設(shè)置透明度

合成

  • 在有多個(gè)圖層重疊的情況下绪撵,屏幕上的人看到的一個(gè)像素點(diǎn)可能是好幾個(gè)像素點(diǎn)合成后的結(jié)果瓢姻,這就需要我們?nèi)ビ?jì)算出現(xiàn)的像素應(yīng)該是什么造型
  • 下面是理想狀態(tài)下的像素合成公式:
R = S + D * ( 1 – Sa )

結(jié)果的顏色 = 源色彩(頂端紋理) + 目標(biāo)顏色(低一層的紋理) * (1 - 源顏色的透明度)
  • 但理想狀態(tài)很少見,更多情況下音诈,我們需要進(jìn)行更為復(fù)雜的計(jì)算

透明與不透明

  • 這里先區(qū)分三個(gè)概念

Alpha幻碱,Hidden與Opaque區(qū)別

  • alpha是不透明度,屬性為浮點(diǎn)類型的值细溅,取值范圍從0到1.0褥傍,表示從完全透明到完全不透明,其特性有當(dāng)前UIView的alpha值會(huì)被其所有subview繼承喇聊。alpha值會(huì)影響到UIView跟其所有subview恍风,alpha具有動(dòng)畫效果。當(dāng)alpha為0時(shí)誓篱,跟hidden為YES時(shí)效果一樣朋贬,但是alpha主要用于實(shí)現(xiàn)隱藏的動(dòng)畫效果,在動(dòng)畫塊中將hidden設(shè)置為YES沒有動(dòng)畫效果
  • 設(shè)置backgroundColor的alpha值只影響當(dāng)前UIView的背景窜骄,并不會(huì)影響其所有subview兄世。Clear Color就是backgroundColor的alpha為1.0。alpha值會(huì)影響backgroundColor最終的alpha,假設(shè)UIView的alpha為0.8啊研,backgroundColor的alpha為0.5御滩,那么backgroundColor最終的alpha為0.4(0.8*0.5)
  • Hidden表示UIView是否隱藏,Hidden設(shè)置為YES表示當(dāng)前UIView的所有subview也會(huì)被隱藏党远,忽略subview的hidden屬性削解。Hidden只要設(shè)置為YES,所有的subview都會(huì)隱藏沟娱。UIView隱藏之后也會(huì)從當(dāng)前的響應(yīng)者事件中移除
  • opaque表示當(dāng)前的UIView的是否不透明【BOOL值】氛驮,但它就是涉及到了像素渲染問題,對(duì)于opaque為1的圖層济似,將會(huì)直接顯示矫废,不會(huì)再去計(jì)算合成

合成區(qū)別

  • 顯然盏缤,盡量多用opaque 為 YES的圖層可以節(jié)約GPU的消耗,加快渲染時(shí)間
  • 如果你加載一個(gè)沒有 alpha 通道的圖片蓖扑,并且將它顯示在 UIImageView 上唉铜,會(huì)自動(dòng)設(shè)置opaque 為 YES
  • 一個(gè)圖片沒有 alpha 通道和一個(gè)圖片每個(gè)地方的 alpha 都是100%,這將會(huì)產(chǎn)生很大的不同律杠。在后一種情況下潭流,Core Animation 需要假定是否存在像素的 alpha 值不為100%,也就是說依然需要進(jìn)行運(yùn)算

對(duì)齊與不對(duì)齊

  • 如果幾個(gè)圖層的模版都是完美重合柜去,那我們只要從第一個(gè)像素到最后一個(gè)像素都計(jì)算合成一下
  • 但是如果像素沒有對(duì)齊好灰嫉,我們還需要額外進(jìn)行額外的移位操作,合并原紋理上的像素
  • 兩種情況會(huì)導(dǎo)致不對(duì)齊出現(xiàn):
    • 第一個(gè)便是縮放嗓奢;當(dāng)一個(gè)紋理放大縮小的時(shí)候讼撒,紋理的像素便不會(huì)和屏幕的像素排列對(duì)齊
    • 另一個(gè)原因便是當(dāng)紋理的起點(diǎn)不在一個(gè)像素的邊界上

離屏渲染(Offscreen Rendering)

  • 在屏幕中,我們要顯示的位圖直接存在當(dāng)前屏幕的后備存儲(chǔ)區(qū)股耽,同時(shí)這一塊內(nèi)容將會(huì)很快被刷新到屏幕上呈現(xiàn)
  • 但加入我們需要寫一個(gè)簡單的平移動(dòng)畫根盒,假設(shè)有60幀動(dòng)畫,那我們就需要重復(fù)生成60個(gè)圖層豺谈,并應(yīng)用
  • 這是因?yàn)槠聊痪瓦@么大郑象,我們放在當(dāng)前屏幕的后備存儲(chǔ)區(qū)必須得是即將放上去的內(nèi)容
  • 這樣的操作方式顯然很浪費(fèi)GPU贡这,所以遇到動(dòng)畫Core Animation會(huì)自動(dòng)觸發(fā)離屏渲染

什么是離屏渲染(Offscreen Rendering)

CRT顯示器

  • CRT顯示器是靠電子束激發(fā)屏幕內(nèi)表面的熒光粉來顯示圖像的茬末,由于熒光粉被點(diǎn)亮后很快會(huì)熄滅,所以電子槍必須循環(huán)地不斷激發(fā)這些點(diǎn)

  • 首先盖矫,在熒光屏上涂滿了按一定方式緊密排列的紅丽惭、綠、藍(lán)三種顏色的熒光粉點(diǎn)或熒光粉條辈双,稱為熒光粉單元责掏,相鄰的紅、綠湃望、藍(lán)熒光粉單元各一個(gè)為一組换衬,學(xué)名稱之為像素。每個(gè)像素中都擁有紅证芭、綠瞳浦、藍(lán)(R、G废士、B)三基色

顯示原理

  • 顯示器顯示出來的圖像是經(jīng)過 CRT電子槍一行一行的掃描.(可以是橫向的也可以是縱向),掃描出來就呈現(xiàn)了一幀畫面,隨后電子槍又會(huì)回到初始位置循環(huán)掃描,為了讓顯示器的顯示跟視頻控制器同步,當(dāng)電子槍新掃描一行的時(shí)候.準(zhǔn)備掃描的時(shí)候,會(huì)發(fā)送一個(gè) 水平同步信號(hào)(HSync信號(hào)),而當(dāng)一幀畫面繪制完成后,電子槍回復(fù)到原位叫潦,準(zhǔn)備畫下一幀前,顯示器會(huì)發(fā)出一個(gè)垂直同步信號(hào)(vertical synchronization簡稱 VSync)
  • 顯示器一般是固定刷新頻率的,這個(gè)刷新的頻率其實(shí)就是VSync信號(hào)產(chǎn)生的頻率. 然后CPU計(jì)算好frame等屬性,就將計(jì)算好的內(nèi)容提交給GPU去渲染,GPU渲染完成之后就會(huì)放入幀緩沖區(qū),然后視頻控制器會(huì)按照VSync信號(hào)逐行讀取幀緩沖區(qū)的數(shù)據(jù),經(jīng)過可能的數(shù)模轉(zhuǎn)換傳遞給顯示器.就顯示出來了

離屏渲染原理

  • 離屏渲染也就是說在屏幕外劃出一片緩存區(qū)作為屏幕外緩存區(qū)官硝,用來存儲(chǔ)需要渲染又不能馬上放入屏幕內(nèi)緩存區(qū)的紋理矗蕊,這塊大小大約有屏幕大小兩倍的空間
  • 這種做法的實(shí)質(zhì)就是將CPU拉來做GPU的事短蜕,讓CPU在屏幕外進(jìn)行渲染工作【雖然CPU性能比GPU強(qiáng)得多,但是在渲染這方面還不如GPU傻咖,用殺雞焉用牛刀的感覺】
  • 離屏渲染這個(gè)機(jī)制出現(xiàn)的原因在于Apple對(duì)于流暢度要求很高朋魔,寧愿用空間【性能】換時(shí)間
  • 但這是一種消耗極大的方式,不僅是CPU渲染有開銷没龙,還包括兩次昂貴的環(huán)境轉(zhuǎn)換(轉(zhuǎn)換環(huán)境到屏幕外緩沖區(qū)铺厨,然后轉(zhuǎn)換環(huán)境到幀緩沖區(qū))
  • 這樣的好處就是可以復(fù)用,避免不必要的GPU渲染
  • 另外復(fù)用也不是隨意復(fù)用的硬纤,這個(gè)可以被復(fù)用的位圖同樣是只能存在一段時(shí)間解滓,之后會(huì)被卸載掉,你需要計(jì)算GPU 的利用率和幀的速率來判斷這個(gè)位圖是否有用

調(diào)試方式

  • 調(diào)試主推薦Instrument里面的Core Animation工具
  • 它可以查看項(xiàng)目的fps筝家,GPU占用率
5FAD78E6BB6CC85AD123A7F166D02A18
  • 但是我遇到了一個(gè)問題就是這個(gè)工具只能在真機(jī)上用洼裤,在模擬機(jī)上都說該設(shè)備不支持這個(gè)操作,不知道是哪一步整錯(cuò)了
  • 另一個(gè)是Xcode -> Debug > View Debugging > Rendering大法
截屏2019-10-15下午8.33.40
  • 這個(gè)請(qǐng)注意要在運(yùn)行的時(shí)候才能點(diǎn)開
  • Color Blended Layers 出現(xiàn)圖層混合的地方會(huì)標(biāo)注為紅色溪王,沒有圖層混合的地方會(huì)顯示為綠色腮鞍,方向是紅色越少越好,綠色越多越好
  • Color Hits Green and Misses Red 當(dāng)使用光柵化渲染(shouldRasterize)的時(shí)候莹菱,如果圖層是綠色移国,表示這些緩存被復(fù)用,如果圖層是紅色表示緩存沒有被復(fù)用會(huì)重復(fù)創(chuàng)建道伟,這時(shí)候會(huì)造成性能問題迹缀。
  • 一般這兩個(gè)用的比較多
  • 還有一個(gè)Color Offscreen-rendered Yellow 用來檢測(cè)是否離屏渲染【off-screen Rendering】
    • GPU的渲染有兩種,On-screen Rendering當(dāng)前屏幕渲染蜜徽,是指GPU的渲染在當(dāng)前屏幕的緩沖區(qū)內(nèi)進(jìn)行祝懂。off-screen Rendering是指在GPU的渲染發(fā)生在當(dāng)前屏幕之外新開辟的緩沖區(qū)。開辟新的緩沖區(qū)拘鞋,切換緩沖區(qū)等會(huì)對(duì)性能有較大的影響
    • 同時(shí)砚蓬,有七種情況會(huì)觸發(fā)離屏渲染
      1. cornerRadius以及masksToBounds同時(shí)使用時(shí)會(huì)觸發(fā)離屏渲染,單獨(dú)使用時(shí)不會(huì)觸發(fā)
      2. 設(shè)置shadow盆色,而且shodowPath = nil時(shí)會(huì)觸發(fā)
      3. mask 設(shè)置蒙版會(huì)觸發(fā)
      4. layer.shouldRasterize的不適當(dāng)使用會(huì)觸發(fā)離屏渲染
      5. layer.allowsGroupOpacity iOS7以后默認(rèn)開啟灰蛙;當(dāng)layer.opacity != 1.0且有subLayer或者背景圖時(shí)會(huì)觸發(fā)
      6. layer.allowsEdgeAntialiasing 在iOS8以后的系統(tǒng)里可能已經(jīng)做了優(yōu)化,并不會(huì)觸發(fā)離屏渲染隔躲,不會(huì)對(duì)性能造成影響
      7. 重寫了drawRect

iOS繪制

CALayer與UIView

<img src="https://tva1.sinaimg.cn/large/006y8mN6ly1g8jqfuqu0wj30eg03paam.jpg" alt="img" style="zoom:200%;" />

  • 每一個(gè)UIView都有一個(gè)layer摩梧,每一個(gè)layer都有個(gè)content,這個(gè)content指向的是一塊緩存蹭越,叫做backing store
  • 在沒有重寫drawRect方法的情況下障本,CALayer的content為空,重寫后系統(tǒng)會(huì)為該layer的content開辟一塊緩存,大小size = width * height * scale驾霜,用來存放drawRect繪制的內(nèi)容【就算重寫內(nèi)容為空也會(huì)新建緩存案训,注意】

代碼驗(yàn)證

//
//  MyView.m
//  TableView-Optimizing-ChemeDemo
//
//  Created by Kevin.J on 2019/11/2.
//  Copyright ? 2019 姜?jiǎng)P文. All rights reserved.
//

#import "MyView.h"

@implementation MyView

-(void)drawRect:(CGRect)rect{
    NSLog(@"4MyView.before.drawRect.layer.contents %@",self.layer.contents);

//   CGContextRef context = UIGraphicsGetCurrentContext();
//   draw something

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"3MyView.after.drawRect.layer.contents %@",self.layer.contents);
    });
}

@end

  
//
//  ViewController.m
//  TableView-Optimizing-ChemeDemo
//
//  Created by Kevin.J on 2019/10/8.
//  Copyright ? 2019 姜?jiǎng)P文. All rights reserved.
//

#import "ViewController.h"
#import "AsyncLabel.h"
#import "MyView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //AsyncLabel *label = [[UILabel alloc] init];
    MyView* myView = [[MyView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"1MyView.after.drawRect.layer.contents %@",myView.layer.contents);
    });
    [self.view addSubview:myView];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"2MyView.after.drawRect.layer.contents %@",myView.layer.contents);
    });
}


@end
輸出的順序?yàn)椋?4MyView.before.drawRect.layer.contents (null)
1MyView.after.drawRect.layer.contents <CABackingStore 0x7f9aa8f00ff0>
2MyView.after.drawRect.layer.contents <CABackingStore 0x7f9aa8f00ff0>
3MyView.after.drawRect.layer.contents <CABackingStore 0x7f9aa8f00ff0>

繪制細(xì)節(jié)

  • CALayer提供了三種繪制內(nèi)容的方式,若采用優(yōu)先級(jí)高的方式繪制了內(nèi)容粪糙,則低優(yōu)先級(jí)的則不會(huì)執(zhí)行
img

繪制時(shí)機(jī)

  • 當(dāng)在操作 UI 時(shí)强霎,比如改變了 Frame、更新了 UIView/CALayer 的層次時(shí)蓉冈,或者手動(dòng)調(diào)用了 UIView/CALayer 的 setNeedsLayout/setNeedsDisplay方法后城舞,這個(gè) UIView/CALayer 就被標(biāo)記為待處理,并被提交到一個(gè)全局的容器去寞酿。
  • 蘋果注冊(cè)了一個(gè) Observer 監(jiān)聽 BeforeWaiting(即將進(jìn)入休眠) 和 Exit (即將退出Loop) 事件家夺,回調(diào)去執(zhí)行一個(gè)很長的函數(shù):
  • _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv()。這個(gè)函數(shù)里會(huì)遍歷所有待處理的 UIView/CAlayer 以執(zhí)行實(shí)際的繪制和調(diào)整伐弹,并更新 UI 界面
  • 當(dāng)UIView被繪制時(shí)(從 CA::Transaction::commit:以后)拉馋,CPU執(zhí)行drawRect,通過context將數(shù)據(jù)寫入backing store惨好。當(dāng)backing store寫完后煌茴,通過render server交給GPU去渲染,將backing store中的bitmap數(shù)據(jù)顯示在屏幕上

參考文章

  1. iOS性能優(yōu)化(初級(jí))
  2. iOS性能優(yōu)化(中級(jí))
  3. iOS性能優(yōu)化(中級(jí)+): 異步繪制
  4. iOS繪制與渲染--CPU繪制
  5. iOS-CPU&&GPU分別做什么日川?
  6. CoreText是如何繪制文本的
  7. 【重讀iOS】認(rèn)識(shí)CALayer
  8. 為什么必須在主線程操作UI
  9. 異步繪制
  10. 位圖:百度百科
  11. 繪制像素到屏幕上
  12. iOS開發(fā)-Alpha蔓腐,Hidden與Opaque區(qū)別
  13. [技巧]UIView的hidden和alpha的妙用
  14. 關(guān)于離屏渲染
  15. iOS-離屏渲染詳解
  16. 離屏渲染優(yōu)化詳解:實(shí)例示范+性能測(cè)試
  17. 淺談iOS中的視圖優(yōu)化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市龄句,隨后出現(xiàn)的幾起案子回论,更是在濱河造成了極大的恐慌,老刑警劉巖撒璧,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件透葛,死亡現(xiàn)場(chǎng)離奇詭異笨使,居然都是意外死亡卿樱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門硫椰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來繁调,“玉大人,你說我怎么就攤上這事靶草√阋龋” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵奕翔,是天一觀的道長裕寨。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么宾袜? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任捻艳,我火速辦了婚禮,結(jié)果婚禮上庆猫,老公的妹妹穿的比我還像新娘认轨。我一直安慰自己,他們只是感情好月培,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布嘁字。 她就那樣靜靜地躺著,像睡著了一般杉畜。 火紅的嫁衣襯著肌膚如雪纪蜒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天此叠,我揣著相機(jī)與錄音霍掺,去河邊找鬼。 笑死拌蜘,一個(gè)胖子當(dāng)著我的面吹牛杆烁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播简卧,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼兔魂,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了举娩?” 一聲冷哼從身側(cè)響起析校,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铜涉,沒想到半個(gè)月后智玻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芙代,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年吊奢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纹烹。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡页滚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铺呵,到底是詐尸還是另有隱情裹驰,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布片挂,位于F島的核電站幻林,受9級(jí)特大地震影響贞盯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沪饺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一邻悬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧随闽,春花似錦父丰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至魏滚,卻和暖如春镀首,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鼠次。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工更哄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腥寇。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓成翩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赦役。 傳聞我的和親對(duì)象是個(gè)殘疾皇子麻敌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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