前言
一直想研究的問題,一直不知道怎么研究的一個問題又官,直到看到了CRT....算大致了解了一些。
問題
一個控件想要顯示在屏幕上我們知道用UIView或者其子類都可以實現(xiàn)赏胚,但是它為什么會顯示在屏幕上?或者它顯示在屏幕上之前都做了什么崖疤?
其實UIView能顯示在屏幕上離不開CALayer的支持,CALayer又是什么劫哼?為什么單獨的UIView就不行眯亦?其實UIView是個容器,CALayer是負(fù)責(zé)繪制妻率,繪制完成交給UIView去顯示宫静。為什么?為什么不讓CALayer直接去顯示伏伯?
那么我就想知道為什么手機屏幕可以顯示這些圖像说搅?
刨根問底的問題不能說沒有意義(要適當(dāng))琢蛤,只是沒有去研究它的原理博其。下面筆者會大致
的介紹一下顯示器成像的原理和iOS應(yīng)用添加一個View為什么可以在屏幕上顯示。(粗略回答,如有錯誤峰髓,感謝您指出。??)
正常我們身邊接觸到的顯示器屏幕携兵,大致可分為CRT,LCD,OLED徐紧,(筆者對硬件是一片空白,能說出這些已經(jīng)很不錯了拂檩。 )
CRT
學(xué)名為:陰極射線顯像管嘲碧,我們主要來介紹它的成像原理愈涩。CRT顯示器能成像的基礎(chǔ)是靠電子束激發(fā)屏幕內(nèi)表面的熒光粉來顯示的履婉,電子束我們通常可以叫做電子槍舰蟆,熒光粉按照一定的方式涂在熒光屏上密密麻麻的排列為紅綠藍(lán)(RGB)三種顏色的熒光粉條稱為熒光粉單元,我們通常稱為這一個單元為一個像素身害,這樣大家理解像素的意思了吧塌鸯。電子槍的工作原理筆者完全看不懂里面的介紹,畢竟術(shù)業(yè)有專攻涨颜,大致上是說庭瑰,通電之后燈絲加熱,陰極發(fā)射電子弹灭,電擊槍以極高的速度去轟擊這些熒光粉層穷吮,受到這些轟擊像素受到電腦顯卡R,G,B三個基色視頻信號的控制饥努,來顯示強弱色酷愧,以此我們才看到了這些豐富多彩的畫面。
電子槍有多種掃描方式伟墙,介紹一種:逐行掃描戳葵,就是一行一行從左到右的掃描拱烁,所以不但電子槍要有橫向移動的能力,還要有縱向和斜向的移動戏自。當(dāng)從左到右然后換行一直到最后成為一幀伤锚,肉眼看起來不卡頓至少要30幀以上,意思就是每秒電子槍要這樣循環(huán)掃描30次以上猛们。
在iPhone8plus上分辨率為1920*1080=2073600弯淘,就是有大約200萬個像素點,所以你知道電子槍得有多辛苦假勿,當(dāng)然CRT這種成像現(xiàn)在的iphone并沒有用转培,但是都是基于三基色RGB去成像的 浆竭。
LCD
LCD簡稱液晶屏兆蕉,它的原理和CRT不同的是他沒有熒光粉,而是利用了彩色濾色片易稠,彩色濾色片就是RGB組成的包蓝,然后在它上面是偏光板测萎,偏光板的作用就是把這些顏色呈現(xiàn)明暗,然后我們?nèi)庋劭吹降木褪遣煌念伾CD的顯示器的每個點都能接收到信號腕唧,不需要電子槍逐行的掃描或辖。
OLED
技術(shù)越先進(jìn)越不好理解,在網(wǎng)上查找的大致是這樣的但惶,它和LCD不同的是湿蛔,LCD需要背光板發(fā)光映射給彩色濾色片煌集,而OLED不需要背光板苫纤,三基色單元本身就會發(fā)光(⊙︿⊙)纲缓,感受到了被技術(shù)支配的恐懼祝高。好啦栗弟, 大致就是這些乍赫。
好吧,實在是編不下去了叠殷,但是成像原理確實是這樣。所以理解我們的iOS應(yīng)用為什么能成像林束,我們只要知道CRT原理就好了缕题,至少還能看懂些,LCD和OLED借助的是高/低分子材料烟零,已經(jīng)涉及到化學(xué)了胸嘁,所以刨根問底適當(dāng)為止性宏。
底層
為什么我們寫一個UIView會顯示在屏幕上?
當(dāng)我們用代碼在Xcode上self.view.addSubView(view1)
然后點擊Run状飞,經(jīng)過編譯,鏈接生成可執(zhí)行文件酵使,模擬器被打開,屏幕過渡動畫到顯示到我們的眼前口渔。
其中顯示這個環(huán)節(jié)是這樣的:我們運行這個程序痪欲,CPU會計算好所有的要顯示的內(nèi)容(CPU是做復(fù)雜計算和處理的中央處理器)然后交給GPU(GPU主要負(fù)責(zé)單一重復(fù)運算,最主要是做圖形方面的渲染)业踢,GPU渲染后將渲染結(jié)果放入幀緩沖區(qū)知举,隨后視頻控制器會逐行讀取幀緩沖區(qū)的數(shù)據(jù)雇锡,經(jīng)過一通我們不懂得操作傳遞給顯示器顯示遮糖。
iOS應(yīng)用
iOS里叠赐,最上層是有SDK提供給我們的UIKit框架去搭建我們的UI芭概,我們通過這個框架能搭建出任意我們想要的頁面,在它下層支持的是CoreAnimation罢洲,CoreAnimation是iOS能顯示控件的核心惹苗,iOS所有的控件幾乎都是CoreAnimation的封裝桩蓉,或者是直接的使用CoreAnimation,CoreAnimation的在下一層是有Metal和CoreGraphics支持洽瞬,他們由OpenGL/OpenGL ES支持本涕,OpenGL/OpenGL ES不是太了解,但是他們應(yīng)該是離硬件最近的了。 蘋果官方并沒有貼出關(guān)于OpenGL/OpenGL ES的東西为障,可能是因為他們要大力推廣Metal的原因鳍怨。
為什么單獨的UIView不能顯示窿冯?
因為UIView只是一個呈現(xiàn)CALayer的容器醒串,CALayer沒有顯示的功能,他要借助UIView這個容器,所以他們是相輔相成的關(guān)系伴逸。UIView設(shè)置的background
,frame
,等等其實都是給CALayer設(shè)置的,可以說UIView只是在CALayer上套了一個殼子错蝴。下面我會猜測一下為什么要這樣顷锰。
為什么不讓CALayer直接去顯示官紫?
這個問題也沒有標(biāo)準(zhǔn)答案,只能是猜測吧.我們打開CALayer的.h文件我們會發(fā)現(xiàn)基本上所有的定義的屬性和函數(shù)都是iOS2.0之后的,所以猜測可能在2.0之前確實使用CALayer去實現(xiàn)單獨顯示的毁涉,但是iOS2.0之后,由于業(yè)務(wù)功能的擴(kuò)展,CALayer越來越大馅精,所以就不能承擔(dān)多業(yè)務(wù)的能力严嗜,所以對每種業(yè)務(wù)都有不同的它的封裝去實現(xiàn),這個應(yīng)該是就做策略模式茄蚯。
/** The base layer class. **/
@available(iOS 2.0, *)
open class CALayer : NSObject, NSSecureCoding, CAMediaTiming
<UILabel: 0x7fdf605092e0; frame = (0 100; 100 30); text = '123456'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60000028c760>>
<_UILabelLayer:0x60000028c760; position = CGPoint (50 115); bounds = CGRect (0 0; 100 30); delegate = <UILabel: 0x7fdf605092e0; frame = (0 100; 100 30); text = '123456'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60000028c760>>; allowsGroupOpacity = YES; contentsMultiplyColor = (null); rasterizationScale = 3; contentsScale = 3>
上面這段代碼我們可以看到CALayer會把UILable隱式的修改為_UILabelLayer
渗常。
參考文獻(xiàn):
Core Animation Programming Guide
CRT顯示器
LCD顯示器
OLED如何成像原理
總結(jié)的不好皱碘,請諒解癌椿。如有錯誤踢俄,請您指正晴及。感謝虑稼。