高性能iOS開發(fā)讀書筆記

老司機(jī)高德納曾經(jīng)說過:程序開發(fā)人員為提升程序效率在錯誤的方向和時間點(diǎn)浪費(fèi)了太多的時間,過早優(yōu)化是編程領(lǐng)域的萬惡之源

1.內(nèi)存優(yōu)化
一個應(yīng)用中內(nèi)存消耗分成兩個部分:一個是??臻g一個是堆空間。
??臻g:每一個線程都會對應(yīng)一個專用的棧空間,??臻g可以在線程存在期間使用,但是有最大棧空間限制。如果超出這個限制,將會導(dǎo)致棧移除,程序被殺死。
以下幾種情況,都是由于棧空間溢出,導(dǎo)致程序被殺死:

  • 可以被遞歸調(diào)用的最大方法數(shù)目。因?yàn)槊恳粋€方法都會對應(yīng)一個棧幀,棧幀會消耗一定字節(jié)的內(nèi)存。(這就是為什么,循環(huán)調(diào)用一定會崩潰,因?yàn)楹瘮?shù)棧幀消耗的字節(jié)數(shù)太多,導(dǎo)致內(nèi)存溢出)
  • 方法中定義的變量個數(shù)太多。當(dāng)然這只是一個理論上可能會導(dǎo)致棧溢出的情況,實(shí)際開發(fā)中基本不會因?yàn)槎x過多變量被系統(tǒng)kill掉
  • 視圖的層級太深。遞歸的調(diào)用layoutSubviews方法跟drawRect方法。
    堆空間:每一個進(jìn)城的所有線程都是會對應(yīng)同一個堆空間。堆空間是系統(tǒng)分配的。通過類創(chuàng)建的對象相關(guān)的所有數(shù)據(jù)都是放在堆中的。所以重量級model在系統(tǒng)收到didReceiveMemoryWarning的時候進(jìn)行清空,然后在必要的時候重新賦值對于系統(tǒng)優(yōu)化是非常必要的。

內(nèi)存管理的原則

  • 你可以擁有你自己創(chuàng)建的對象,比如 new,alloc,copy,mutablecopy
  • 你可以使用MRC中的retain 或者是ARC中的_Strong來標(biāo)示對一個對象的強(qiáng)引用
  • 在MRC中當(dāng)不需要一個對象的時候,需要使用release方法來釋放對象的持有關(guān)系,ARC中不需要做任何操作

避免循環(huán)引用引發(fā)的內(nèi)存泄漏
1.delegate weak修飾
2.__weak 修飾被block捕獲的局部變量
3.NSTimer,對象持有定時器,定時器也持有對象。解決方法1.自定義清理時機(jī),可以退出控制器時,也可以點(diǎn)擊某一個按鈕時。

2.能耗
基本沒什么好說的,無關(guān)緊要
3.多線程
記?。褐骶€程用來更新UI,自線程用來做讀寫文件等比較耗時的操作
每個線程大概會消耗1KB的內(nèi)核內(nèi)存空間。主線程會占用1MB的棧空間,子線程會占用512KB的棧空間。
多線程的弊端:

  • 上下文切換,耗費(fèi)時間
  • 創(chuàng)建耗費(fèi)時間,一般一條線程創(chuàng)建之后啟動大概耗費(fèi)29毫秒
    三種多線程的比較
    1.GCD
  • 抽象程度高
  • 兩種隊(duì)列開箱即用:main和global
  • 可以創(chuàng)建更多的隊(duì)列
  • 硬性要求少于64個線程

2.NSOperationQueue

  • 無默認(rèn)隊(duì)列
  • 應(yīng)用管理自己創(chuàng)建的隊(duì)列
  • 隊(duì)列是優(yōu)先級的隊(duì)列
  • 操作可以有不同的優(yōu)先級
  • 使用cancel可以取消操作
  • 可以等待某個操作執(zhí)行完成

屬性默認(rèn)實(shí)用的是atomic,但是這樣做屬性也不一定是線程安全的。如果需要做線程安全操作,更好的是用鎖。所以不要將屬性設(shè)置為atomic。
注意:@synchronized指令會拖慢應(yīng)用的運(yùn)行速度,因?yàn)樵谌魏螘r間內(nèi)都只有一個線程在臨界區(qū)。
以下是三種比較常用的鎖
1.NSLock
這是一種低級別的鎖,一旦獲得了鎖,那么將會執(zhí)行臨界區(qū)中的內(nèi)容,并且不會超過一個線程執(zhí)行。釋放鎖則標(biāo)志著臨界區(qū)結(jié)束。有個注意點(diǎn)就是 釋放鎖的操作一定要跟加鎖操作在同一線程。
2.NSRecursiveLock
在調(diào)用lock之前,NSLock必須先調(diào)用unlock。但是正如名字暗示的那樣,NSRecursiveLock允許在被解鎖之前鎖定多次。只要解鎖的次數(shù)跟鎖定的次數(shù)相匹配,那么鎖就可以釋放。

image.png

上圖是各種鎖的性能。附上老司機(jī)的關(guān)于iOS中鎖問題研究文章鏈接:https://bestswifter.com/ios-lock/

4.應(yīng)用的首次啟動時間
應(yīng)用首次啟動往往會做很多事情,包括
1.加載默認(rèn)項(xiàng)
2.檢查測試版本
3.初始化應(yīng)用標(biāo)識符
4.初始化崩潰報(bào)告
5.建立分析方法
6.建立UI基礎(chǔ)框架
7.建立內(nèi)存緩存
附上 今日頭條開機(jī)啟動優(yōu)化的文章:http://www.cocoachina.com/ios/20170208/18651.html

5.UI層面的優(yōu)化
記住下面幾個原則

  • 盡量減少主線程中的工作
  • 避免視圖層級中的多層嵌套
  • 盡可能的延遲視圖的加載,也就是常說的懶加載。并且對于可以重用的視圖,進(jìn)行復(fù)用 https://github.com/facebookarchive/AsyncDisplayKit
  • UIImageView 注意分場景下使用imageNamed跟imageWithContentsofFile。使用圖片與imageView大家接近,避免imageview對圖片縮放操作。
  • UITableView的優(yōu)化:http://www.itdecent.cn/p/4780b10dae55
  • 慎用自動布局。自動布局在視圖比較多的時候非常耗費(fèi)CPU性能。如果頁面元素太多,建議使用原生的frame布局,對于提升幀率有非常大的幫助。當(dāng)然了marsory對于計(jì)算布局有非常大的幫助,往往很復(fù)雜的約束,frame要寫一大堆代碼,但是marsory就可以寫幾行就可以了。根據(jù)業(yè)務(wù)不同,可以自己做選擇。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,787評論 11 349
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,893評論 25 709
  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,894評論 0 11
  • 曾經(jīng)的我,認(rèn)為 教師,是為人師表、無私奉獻(xiàn)、人類文明的階梯的代名詞 醫(yī)生,是救死扶傷的代名詞 現(xiàn)在的我,認(rèn)為 不管...
    廢柴少爺閱讀 569評論 0 0
  • 不知不覺,又到了中午十二點(diǎn)。吃午飯的時間到了,饑餓的人紛紛坐到了餐桌周圍。 飯菜端上來了,還是一如既往的米飯,大家...
    上官飛鴻閱讀 444評論 7 21

友情鏈接更多精彩內(nèi)容