Layer學(xué)習(xí)筆記

筆記主要來源iOS核心動畫高級技巧,感謝作者與翻譯的各位同學(xué).

一平斩、圖層樹

  • UIView夫椭、NSView都有一個關(guān)聯(lián)的CALayer劣欢,不用CALayer處理所有事情的原因是為了職責(zé)分離盛垦,在iOS和Mac OS兩個平臺上湿弦,事件和用戶交互有很多地方的不同.

二、寄宿圖

  • UIView有個contentMode屬性腾夯,經(jīng)常在它的子類UIImageView上使用颊埃,而實際上這個屬性是對應(yīng)CALayer的contentGravity屬性的,并且CALayer的contentGravity屬性是NSString類型蝶俱,可選的常量值如下:

    * KCAGravityCenter
    * KCAGravityTop
    * KCAGravityBottom
    * KCAGravityLeft
    * KCAGravityRight
    * KCAGravityTopRight
    * KCAGravityBottomLeft
    * KCAGravityBottomRight
    * KCAGravityResize
    * KCAGravityResizeAspect
    * KCAGravityResizeAepectFill
    
  • contentScale屬性定義了寄宿圖的像素尺寸和視圖大小的比例班利,默認值為1.0,contentScale屬性屬于支持高分辨率屏幕機制的一部分(與圖片的2x,3x使用相對應(yīng),iPhone4榨呆、5罗标、6系列均為2.0,iPhone6p系列均為3.0).為了使圖片顯示爭取可設(shè)置layer.contentScale = [UISCreen mainScreen].scale;

  • maskToBounds屬性與UIView的clipsToBounds屬性對應(yīng),決定是否顯示超出邊界的內(nèi)容.

  • contentsRect屬性CALayer的contentsRect屬性允許我們在圖層邊框里顯示寄宿圖的一個子域.和bounds愕提,frame不同馒稍,contentsRect不是按點來計算的皿哨,它使用了單位坐標浅侨,單位坐標指定在0和1之間,是一個相對值.iOS的坐標系統(tǒng):

    • 點 —— 在iOS和Mac OS中最常見的坐標體系证膨。點就是虛擬的像素如输。也被稱作邏輯像素。在標準設(shè)備上,一個點就是一個像素點不见,但是在retina設(shè)備上澳化,一個點等于2*2個像素。

    • 像素——物理像素坐標并不會用來屏幕布局稳吮,但是仍然與圖片有相對關(guān)系缎谷。UIImage是一個屏幕分辨率解決方案,所以指定點來度量大小灶似。但是一些底層的圖片表示如CGImage就會使用像素列林,所以你要清楚在Retina設(shè)備和普通設(shè)備上,他們表現(xiàn)出來了不同的大小酪惭。

    • 單位——對于與圖片或者圖層邊界相關(guān)的顯示希痴,單位坐標是一個方便的度量方式,當大小改變的時候春感,也不需要再次調(diào)整砌创。單位坐標在OpenGL這種紋理坐標系統(tǒng)中用得很多,Core Animation中也用到了單位坐標鲫懒。

      ?

    默認的contentsRect是{0,0,1,1}嫩实,這意味著整個寄宿圖默認都是可見的.詳細的使用參考Layer的寄宿圖contents屬性.

  • contentsCenter屬性.可以用Interface Builder探測窗口控制contentsCenter屬性(View里).

  • Custom Drawing

    -drawRect:方法沒有默認的實現(xiàn),如果不需要自定義的繪制窥岩,就不要創(chuàng)建這個方法舶赔,這會造成CPU資源和內(nèi)存浪費。雖然-drawRect:方法是一個UIView方法谦秧,事實上都是底層的CALayer安排了重繪工作和保存了因此產(chǎn)生的圖片竟纳。CALayer有一個可選的delegate屬性,實現(xiàn)了CALayerDelegate,當CALayer需要一個內(nèi)容特定的信息時,就會從協(xié)議中請求疚鲤。當需要被重繪時锥累,CALayer會請求它的代理來給他一個寄宿圖來顯示。它通過調(diào)用這個方法做到:

    -(void)displayLayer:(CALayer *)layer
    

    如果代理不實現(xiàn)-displayLayer:方法集歇,CALayer就會轉(zhuǎn)而嘗試調(diào)用下面這個方法:

    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
    

    提供了以上方法桶略,可以使用CALayer的display去強制layer去繪制。

    UIView創(chuàng)建了它的宿主圖層時诲宇,它就會自動地把圖層的delegate設(shè)置為它自己际歼,并提供了一個-displayLayer:的實現(xiàn)。所以一般繪制調(diào)用UIView的-drawRect:方法就可以姑蓝。

三鹅心、圖層幾何學(xué)

  • 布局

    UIView的三個屬性frame,bounds,center對應(yīng)CALayer的三個屬性frame,bounds,postioncenterposition都代表了相對于父圖層anchorPoint所在的位置.

    視圖的frame,boundscenter屬性僅僅是存取方法纺荧,當操縱視圖的frame,實際上是在改變視圖下方CALayerframe旭愧,不能夠獨立于圖層之外改變視圖的frame颅筋。

    對于視圖或者圖層來說,frame并不是一個非常清晰的屬性输枯,它其實是一個虛擬屬性议泵,是根據(jù)bounds,boundstransform計算而來,所以當其中任何一個值發(fā)生改變桃熄,frame都會變化先口。相反,改變frame的值同樣會影響到他們當中的值瞳收。

  • 錨點(anchorPoint)可以參考這篇文章

  • 坐標系.

    一個圖層的position依賴于它父圖層的bounds,如果父圖層發(fā)生了變化池充,它的所有子圖層也會跟著移動.CALayer給不同坐標系之間的圖層轉(zhuǎn)換提供了一些工具類方法:

    - (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer;
    - (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer;
    - (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;
    - (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;
    
  • Hit Testing.

    CALayer并不關(guān)心任何響應(yīng)事件,所以不能直接處理觸摸事件或者手勢缎讼。但是它有一系列的方法幫你處理事件:-containsPoint:-hitTest:.

    hitTest:方法同樣接受一個CGPoint類型參數(shù)收夸,而不是BOOL類型,它返回圖層本身血崭,或者包含這個坐標點的葉子點圖層卧惜。

需要注意的是,當調(diào)用圖層的-hitTest:方法時夹纫,測算的順序嚴格依賴于圖層樹當中的圖層順序(和UIView處理事件類似).zPosition屬性可以明顯改變屏幕上圖層的順序咽瓷,但不能改變事件傳遞的順序。

四舰讹、視覺效果

  • 圓角.

  • 圖層邊框.

    邊框是繪制在圖層邊界里面的茅姜,而且在所有子內(nèi)容之前,也在子圖層之前月匣。邊框并會把寄宿圖或者子圖層的形狀計算進來钻洒,如果圖層的子圖層超過了邊界,或者是寄宿圖在透明區(qū)域有一個透明的蒙版锄开,邊框仍然會沿著圖層的邊界繪制出來素标。

  • 陰影.

    • shadowOpacity
    • shadowColor
    • shadowOffest,該屬性控制著陰影的方向和距離。它是一個CGSize的值萍悴,寬度控制著陰影橫向的位移头遭,高度控制著縱向的位移。shadowOffese的默認值是{0,-3}癣诱,即陰影相對于Y軸有3個點的向上位移计维。
    • shadowRadius,該屬性控制著陰影的模糊的撕予,當它的值是0的時候鲫惶,陰影就和視圖一樣有一個非常確定的邊界線。當值越來越大的時候嗅蔬,邊界線看上去就會越來越模糊和自然.(所以不要設(shè)置為0)剑按。
    • shadowPath.
  • 圖層蒙版.

    mask圖層的color屬性是無關(guān)緊要的疾就,真正重要的是圖層的輪廓澜术。mask屬性就像是一個餅干切割機艺蝴,mask圖層實心的部分被保留下來,其他的則會被拋棄鸟废。

  • 拉伸過濾.

  • 組透明.

    UIViewalpha屬性與CALayeropacity屬性相對應(yīng)猜敢。

五、變換

  • 仿射變換.

    UIView的transform與CALayer的affineTransform相對應(yīng),都是CGAffineTransform類型盒延,用于在二維空間做旋轉(zhuǎn)缩擂,縮放和平移。CGAffineTransform是一個可以和二維空間向量做乘法的3*2矩陣添寺。

  • 3D變換

    CALayer的屬性transformCATransform3D類型 ,CATransform3D也是一個矩陣胯盯,是一個可以在3維空間內(nèi)做變換的4*4矩陣。

六计露、專用圖層

  • CAShapeLayer(十分重要)
  • CATextLayer
  • CAGradientLayer. CAGradientLayer是用來生成兩種或更多顏色平滑漸變的博脑。
  • CAScrollLayer
  • AVPlayerLayer(十分重要).

七、隱式動畫

  • 事務(wù)

    Core Animation基于一個假設(shè)票罐,屏幕上的任何東西都可以(或者可能)做動畫叉趣。動畫并不需要你在Core Animation中手動打開,相反需要明確的關(guān)閉该押,否則它會一直存在.

    事務(wù)事件上是Core Animation用來包含一系列屬性動畫集合的機制疗杉,任何用指定事務(wù)去改變可以做動畫的圖層屬性都不會立刻發(fā)送變化。而是當事務(wù)一旦提交的時候開始用一個動畫過渡到新值蚕礼。

    事務(wù)是通過CATransaction類來做管理烟具, CATransaction沒有屬性或者實例方法,并且也不能用+alloc-init方法創(chuàng)建它奠蹬。但是可以用+begin+commint分別來入棧和出棧.

    Core Animation在每個run loop周期中自動開始一次新的事務(wù)(run loop是iOS負責(zé)收集用戶輸入净赴,處理定時器或者網(wǎng)絡(luò)事件并且重新繪制屏幕的東西),即使你不顯式的用[CATransaction begin]開始一次事務(wù)罩润,任何在一次run loop循環(huán)中屬性的改變都會被機種起來玖翅,然后做一次0.25秒的動畫。

    UIView有兩個方法割以,+beginAnimations:context:+commitAnimations,和CATransactionbegincommit方法類似金度。實際上在+beginAnimations:context+commitAnimations之間所有視圖或者圖層屬性的改變而做的動畫都是由于設(shè)置了CATransaction的原因。在iOS4中严沥,蘋果對UIView添加了一種基于block的動畫:+animateWithDuration:animations:.實質(zhì)上它們都是在做同樣的事情猜极。

  • 完成塊

  • 圖層行為

    Core Animation通常對CALayer的所有屬性(可動畫的屬性)做隱式動畫,但UIView把它關(guān)聯(lián)的圖層的這個屬性關(guān)閉了消玄。

  • 呈現(xiàn)于模型

    CALayer的屬性行為其實很不正常跟伏,因為改變一個圖層的屬性并沒有立即生效丢胚,而是通過一段時間漸變更新。

    當你改變一個圖層的屬性受扳,屬性值的確立刻更新的携龟,但是在屏幕上并沒有馬上發(fā)生改變。這是因為你設(shè)置的屬性并沒有直接調(diào)整圖層的外觀勘高,相反峡蟋,它只是定義了圖層動畫結(jié)束之后將要變化的外觀。

    在iOS中华望,屏幕每秒鐘重繪60次蕊蝗。如果動畫時長比60分之一要長,Core Animation就需要在設(shè)置一次新值和新值生效之間,對屏幕上的圖層進行重新組織赖舟。這意味著CALayer除了“真實”值(就是你設(shè)置的值)之外蓬戚,必須要知道當前顯示在屏幕上的屬性值的記錄。

    通過presentationLayer來獲取屏幕上真正顯示出來的值;而在presentationLayer上調(diào)用-modelLayer將會返回它正在呈現(xiàn)所依賴的layer.

    如果想讓做動畫的圖層響應(yīng)用戶輸入宾抓,可以使用-hitTest:方法子漩,來判斷呈現(xiàn)圖層(presentationLayer)是否被觸摸來響應(yīng)。(具體代碼請參考原書籍)

八洞慎、顯式動畫

  • 屬性動畫

    • CABasicAnimation

      當更新屬性的時候痛单,我們需要設(shè)置一個新的事務(wù),并且禁用圖層行為劲腿。否則動畫會發(fā)生兩次旭绒,一個是因為顯式的CABasicAnimation,另一次是因為隱式動畫。(在設(shè)置屬性的時候)

      通過keyPath焦人、fromValue挥吵、toValue設(shè)置動畫,fromValue可以不設(shè)置.byValue是一個相對值花椭,會從當前的值上動畫到byValue的值忽匈。

    • CAKeyframeAnimation(關(guān)鍵幀動畫)

      屬性動畫通過設(shè)置keyPathvalues屬性得以實現(xiàn)關(guān)鍵幀動畫;還可以通過設(shè)置CGPath來實現(xiàn)一個路徑相關(guān)的動畫矿辽,另外丹允,設(shè)置rotationMode屬性為KCAAnimationRotateAuto,圖層將會根據(jù)曲線的切線自動旋轉(zhuǎn)袋倔。

    • 虛擬屬性

      • transform.rotation
      • transform.postion
      • transform.scale

      keyPath可以設(shè)置為以上三個虛擬屬性雕蔽,然后再通過byValuetoValue來設(shè)置需要動畫的值宾娜。

  • CAAnimationGroup(動畫組)

  • 過渡

    最常見到的過渡就是在childViewController之間切換view.

    為了創(chuàng)建一個過渡動畫批狐,將使用CATransiton,同樣是另一個CAAnimation的子類前塔,和別的子類不同嚣艇,CATransiton有一個Typesubtype來標識變換效果.type屬性是一個NSString類型承冰,可以被設(shè)置成以下值:

    KCATransitionFade
    KCATransitionMoveIn
    KCATransitionPush
    KCATransitionReveal
    

    隱式過渡.當設(shè)置CALayercontent屬性的時候,CATransition的確是默認的行為食零。但是對于視圖關(guān)聯(lián)的圖層困乒,或者其他隱式動畫的行為,這個特性依然是被禁用的慌洪。

  • 在動畫過程中取消動畫

    為了終止一個指定的動畫,你可以用如下方法把它從圖層移除掉:

    -(void)removeAnimationForKey:(NSString *)key;
    

    或者移除所有的動畫:

    -(void)removeAllAnimations;
    

    動畫一旦被移除顶燕,圖層的外觀就立刻更新到當先的模型圖層的值凑保。一般來說冈爹,動畫在結(jié)束之后被自動移除,除非設(shè)置removeAllAnimationNO欧引,如果你設(shè)置動畫在結(jié)束之后不被自動移除频伤,那么當它不需要的時候你要手動移除它;否則它會一直存在于內(nèi)存中芝此,直到圖層被銷毀憋肖。

九、圖層時間

  • CAMediaTiming協(xié)議

    CAMediaTiming協(xié)議定義了在一段動畫內(nèi)用來控制逝去時間的屬性的集合婚苹,CALayerCAAnimation都實現(xiàn)了這個協(xié)議岸更,所以時間可以被任意基于一個圖層或者一段動畫的類控制。

    • 持續(xù)和重復(fù)

      duration是一個CFTimeInterval類型膊升,對將要進行的動畫的一次迭代指定了時間;repeatCount代表動畫重復(fù)的迭代次數(shù)怎炊。例如,duration是2廓译,repeatCount是3.5评肆,那么完整的動畫時長將是7秒。

    • 相對時間

      beginTime指定動畫開始之前的延遲時間非区。這里的延遲是從動畫添加到可見圖層的那一刻開始測量瓜挽,默認是0(就是說動畫會立刻執(zhí)行)。

      speed是一個時間的倍數(shù)征绸,默認1.0久橙,減少它會減慢圖層/動畫的時間,增加它會加快速度管怠。如果speed為2.0,那么對于一個duration為1的動畫淆衷,實際上在0.5秒的時候就已經(jīng)完成了。

      timeOffset讓動畫快進到某一點排惨,例如吭敢,對于一個持續(xù)1秒的動畫來說,設(shè)置timeOffset為0.5意味著動畫將從一般的地方開始暮芭。需要注意的是鹿驼,和beginTime不同的是欲低,timeOffset并不受speed的影響。所以如果你把speed設(shè)置為2.0畜晰,把timeOffset設(shè)置0.5砾莱,那么你的動畫將從動畫最后結(jié)束的地方開始,因為1秒的動畫實際上被縮短到了0.5秒凄鼻。然而即使使用了timeOffset讓動畫從結(jié)束的地方開始腊瑟,它仍然播放了一個完整的時長,這個動畫僅僅是循環(huán)了一圈块蚌,然后從頭開始播放闰非。

    • fillMode

      fillModel是一個NSString類型,可以接受如下四種常量:

      KCAFillModeForwards
      KCAFillModeBackwards
      KCAFillModeBoth
      KCAFillModeRemoved
      

      默認是KCAFillModeRemoved峭范,當動畫不再播放的時候就顯示圖層模型指定的值财松,剩下的三種類型,向前纱控、向后或者即向前又向后去填充動畫狀態(tài)辆毡,使得動畫在開始前或者結(jié)束后仍然保持開始和結(jié)束那一刻的值。

      這就對避免對動畫結(jié)束的時候急速返回提供了另一種方案甜害。但是舶掖,當它來解決這個問題的時候,需要把removeOnCompletion設(shè)置為NO尔店,另外需要給動畫添加一個非空的鍵眨攘,于是可以在不需要動畫的時候把它從圖層上移除。

  • 層級關(guān)系時間

    每個動畫和圖層在時間上都有它自己的層級概念闹获,相對于它的父親來測量期犬,對圖層調(diào)整時間將會影響到它本身和子圖層的動畫,但不會影響到父圖層避诽。

    CALayer或者CAGroupAnimation調(diào)整durationrepeatCount龟虎、repeatDuration屬性并不會影響到子動畫。但是beginTime沙庐、timeOffsetspeed屬相將會影響到子動畫鲤妥。

    CoreAnimation有一個全局時間的概念—馬赫時間。馬赫時間在設(shè)備上所有進程都是全局的拱雏,但是在不同的設(shè)備上并不是全局的(手機休眠時棉安,馬赫時間會暫停),但是比較兩次馬赫時間差很有價值。訪問馬赫時間:

    CFTimeInterval time = CACurrentMediaTime();
    
  • 手動動畫

    timeOffset一個很有用的功能在于它可以讓你手動控制動畫進程铸抑,通過設(shè)置speed為0贡耽,可以禁用動畫的自動播放,然后用timeOffset來來回顯示動畫序列。這可以使得運用手勢來控制動畫變得很簡單蒲赂。

  • 總結(jié)

十阱冶、緩沖

  • 動畫速度

    使用緩沖方程式需要設(shè)置CAAnimationtimingFunction屬性,timingFunctionCAMediaTimingFunction類的一個對象;如果想改變隱式動畫的計時函數(shù)滥嘴,同樣也可以使用CATransaction+setAnimationTimingFunctions:方法木蹬。

    創(chuàng)建CAMediaTimingFunction的最簡單的方式是調(diào)用+timingFuctionWithName:的構(gòu)造方法。傳入的常量如下:

    KCAMediaTimingFunctionLinear
    KCAMediaTimingFunctionEaseIn
    KCAMediaTimingFunctionEaseOut
    KCAMediaTimingFunctionEaseInEaseOut
    KCAMediaTimingFunctionDefault
    
  • 自定義緩沖函數(shù)

十一若皱、基于定時器的動畫

  • 定時幀

    iOS按照每秒60次刷新屏幕镊叁,用定時器1/60秒去更新view的屬性便可以實現(xiàn)定時幀動畫.

    • NSTimer

      iOS上的每個線程都管理了一個NSRunloop,字面上看就是通過一個循環(huán)來完成一些任務(wù)列表走触。但是對主線程晦譬,這些任務(wù)包含如下幾項:

      • 處理觸摸事件
      • 發(fā)送和接受網(wǎng)絡(luò)數(shù)據(jù)包
      • 執(zhí)行使用GCD的代碼
      • 處理計時器的行為
      • 屏幕重繪

      當設(shè)置一個NSTimer,他會被插入到當前任務(wù)列表中饺汹,然后知道指定的時間過去之后才會被執(zhí)行蛔添。但是何時啟動定時器并沒有一個時間上限痰催,而且它只會在列表中上一個任務(wù)完成之后開始執(zhí)行兜辞。這通常會有幾毫秒的延遲,但是如果上一個任務(wù)過了很久才完成就會導(dǎo)致延遲很長一段時間夸溶。

      如何精確動畫:

      • 可以用CADisplayLink讓更新頻率嚴格控制在屏幕刷新之后.
      • 基于真實幀的持續(xù)時間而不是假設(shè)的更新頻率來做動畫(通過兩次馬赫時間差來取動畫幀).
      • 調(diào)整動畫計時器的runloop模式逸吵,這樣就不會被別的事件干擾.
    • CADisplayLink

      CADisplayLink是CoreAnimation提供的類似NSTimer的類,它總是在屏幕完成一次更新之前啟動缝裁。CADisplayLink有一個整型的frameInterval屬性扫皱,指定了間隔多少幀之后才執(zhí)行。默認值是1捷绑,意味著每次屏幕更新之前都會執(zhí)行一次韩脑。但是如果動畫的代碼執(zhí)行起來超過了六十分之一秒,你可以指定frameInterval為2粹污,就是說動畫每隔一幀執(zhí)行一次段多。

    • Run Loop模式

      常見的run loop模式:

      • NSDefaultRunLoopModel - 標準優(yōu)先級
      • NSRunLoopCommonModes - 高優(yōu)先級
      • UITrackingRunLoopMode - 用于UISCrollView和別的控件的動畫

      可以對CADisplayLink指定多個run loop模式,于是我們可以同時加入NSDefaultRunLoopModeUITrackingRunLoopMode來保證它不會被滑動打斷壮吩,也不會被其他UIKit控件動畫影響性能进苍,像這樣:

      self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(step:)];
      [self.timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
      [self.timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
      

      NSTimer同樣:

      self.timer = [NSTimer timerWithTimeInterval:1/60.0
                                       target:self
                                     selector:@selector(step:)
                                     userInfo:nil
                                      repeats:YES];
      [[NSRunLoop mainRunLoop] addTimer:self.timer
                                forMode:NSRunLoopCommonModes];
      

十二、性能調(diào)優(yōu)

  • CPU VS GPU

  • 測量鸭叙,而不是猜測

    可以在程序中用CADisplayLink來測量幀率(用兩次馬赫時間差的倒數(shù)即為幀率)

  • Instruments

    • Time Profiler
    • Leaks
    • Core Animation
    • Allocations
    • GPU Driver

十三觉啊、高效繪圖

  • 軟件繪圖

    在iOS中,軟件繪圖通常是由Core Graphics框架完成沈贝。但是在一些必要的情況下杠人,相比Core Animation和OpenGL, Core Graphics要慢不少。

    一旦實現(xiàn)了CALayerDelegate協(xié)議中的-drawLayer:inContext:方法或者UIView中的-drawRect:方法(其實就是前者的包裝方法),圖層就創(chuàng)建了一個繪制上下文嗡善,這個上下文需要的大小的內(nèi)存可從這個算式得出:圖層寬圖層高4字節(jié)市俊,寬高的單位均為像素。對于一個在Retina iPad上的全屏圖層來說滤奈,這個內(nèi)存量就是 2048*1526*4字節(jié)摆昧,相當于12MB內(nèi)存,圖層每次重繪的時候都需要重新抹掉內(nèi)存然后重新分配(所以一般還是不要重寫view的-drawRect:方法)蜒程。

  • 矢量圖形

    在某些情況下绅你,需要使用Core Graphics來繪圖:

    • 任意多邊形(不僅僅是一個矩形)
    • 斜線或曲線
    • 文本
    • 漸變

    但Core Animation實際上為這樣的繪制提供了專門的類,如CAShapeLayer繪制多邊形昭躺、直線和曲線,CATextLayer繪制文本,CAGradientLayer用來繪制漸變忌锯。

  • 臟矩形

  • 異步繪制

十四、圖像IO

  • 加載和潛伏
    • +imageNamed:方法會解壓圖片领炫,并緩存圖片偶垮,但是+imageNamed:只對應(yīng)用資源束中的圖片有效,所以對用戶生成的圖片或者下載的圖片就沒法使用了帝洪。
    • +imageWithContentsOfFile:加載大圖片比較耗時似舵,并且不會解壓圖片。如果要實現(xiàn)主線程快速加載圖片葱峡,需要在后臺線程加載圖片數(shù)據(jù)并強制解壓砚哗。
    • 第三方庫SDWebImage實現(xiàn)了圖片的下載、解壓砰奕、緩存蛛芥,可以多學(xué)習(xí)。
  • 緩存
    • NSCache
      • -setCountLimit:军援,設(shè)置緩存數(shù)量唬格。
      • -setObject:forKey:cost:膘滨,對每個存儲的對象指定消耗的值來提供一些暗示嘀掸。
      • -setTotalCostLimit:,設(shè)置全體緩存的尺寸赴魁。
      • NSCache在系統(tǒng)低內(nèi)存的時候自動丟棄存儲的對象。
  • 文件格式

十五烘嘱、圖層性能

  • 隱式繪制

  • 離屏渲染

    當圖層屬性的混合體被指定為在未預(yù)合成之前不能直接在屏幕中繪制時昆禽,屏幕外渲染就被喚起了。屏幕外渲染并不意味著軟件繪制蝇庭,但是它意味著圖層必須在被顯示之前在一個屏幕外上下文中被渲染(不論CPU還是GPU)醉鳖。圖層的以下屬性將會觸發(fā)屏幕外繪制:

    • 圓角(當和maskToBounds一起使用時)
    • 圖層蒙板
    • 陰影

    對于那些需要動畫而且要在屏幕外渲染的圖層來說,你可以用CAShapeLayer哮内,contentsCenter或者shadowPath來獲得同樣的表現(xiàn)而且較少地影響到性能盗棵。

  • 混合和過渡繪制

    透明壮韭、半透明顏色的View,會增加GPU的計算纹因,降低性能喷屋。shouldRasterize屬性的使用。

  • 減少圖層數(shù)量

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞭恰,一起剝皮案震驚了整個濱河市屯曹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惊畏,老刑警劉巖恶耽,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颜启,居然都是意外死亡偷俭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門缰盏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涌萤,“玉大人,你說我怎么就攤上這事口猜「合” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵暮的,是天一觀的道長笙以。 經(jīng)常有香客問我,道長冻辩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任拆祈,我火速辦了婚禮恨闪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘放坏。我一直安慰自己咙咽,他們只是感情好,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布淤年。 她就那樣靜靜地躺著钧敞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪麸粮。 梳的紋絲不亂的頭發(fā)上溉苛,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機與錄音弄诲,去河邊找鬼愚战。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的寂玲。 我是一名探鬼主播塔插,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拓哟!你這毒婦竟也來了想许?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤断序,失蹤者是張志新(化名)和其女友劉穎伸刃,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逢倍,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡捧颅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了较雕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉哑。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亮蒋,靈堂內(nèi)的尸體忽然破棺而出扣典,到底是詐尸還是另有隱情,我是刑警寧澤慎玖,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布贮尖,位于F島的核電站,受9級特大地震影響趁怔,放射性物質(zhì)發(fā)生泄漏湿硝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一润努、第九天 我趴在偏房一處隱蔽的房頂上張望关斜。 院中可真熱鬧,春花似錦铺浇、人聲如沸痢畜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丁稀。三九已至,卻和暖如春倚聚,著一層夾襖步出監(jiān)牢的瞬間线衫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工秉沼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桶雀,地道東北人矿酵。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像矗积,于是被迫代替她去往敵國和親全肮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

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