ios性能專題分爲幾大塊:
1.內存:
問題:佔用內存過多會影響性能,應用被kill;內存釋放不當會導致crash;內存是所有app共享的,單個app不應占用大量內存;內存與性能需要一個平衡;系統會幫你殺其它後臺應用,但這影響整體體驗,因此應限制自身app內存佔用量;
理論:類linux系統,但ios無磁盤交換分區,因此內存有限;
自動垃圾收集:mac os x程序開發可用,ios開發不支持,自動垃圾收集時會引起程序暫時中斷;未來os x也將棄用;
手動內存管理原則:
a)想一個對象100%不被釋放,使用retain,但使用過後一定要release;
b)release只會將引用計數-1,而不會釋放內存,只有引用計數爲0時纔會調用dealloc;
c)對於對象的屬性如果有retain或copy/mutableCopy/alloc/new的屬性,一定要在dealloc中釋放之;
d)如果方法中不需要該對象,但需要將其返回,使用autorelease;
e)系統會在自動釋放池釋放時release其中所有對象,但是如果release後計數不爲0,對象不會釋放;
ARC理論:
a)dealloc不能顯式觸發,retain/release/retainCount/autorelease等不能重載或調用;禁止使用 @selector(retain)和@selector(release)
b)dealloc方法中不需要釋放成員變量,不需要調用父類的dealloc;
c)不能在c的結構體中使用對象指針;建議使用對象來存儲數據,而不是結構體;
d)id到void *類型轉換必須是顯式的;
e)@autoreleasepool代替NSAutoreleasePool;
f)不能使用內存分區參數;這參數本來也沒什麼用;
g)以alloc、new、copy、mutableCopy開頭的函數表示調用者對被創建的對象擁有所有權,以init開頭的函數表示對對象進行初始化。這些函數需要是實例方法(而非類方法),並且返回一個對象。如果不遵循這樣的方式,有可能會被搞亂;比如new的方法是非arc的,裏面沒有持有該對象而使用的autorelease,而調用者是arc的,會認爲該方法實際持有了該對象,因此會在後續釋放該對象,造成crash;
h)__bridge、__bridge_retained和__bridge_transfer,用來在c指針和oc指針之間做轉換用,比如void *p = (__bridge void *)obj。三個關鍵字分別表示沒有所有權轉移的類型轉換、前後都擁有所有權的類型轉換以及所有權轉移(交接)的類型轉換。
i)
__strong |
__weak |
__unsafe_unretained |
__autoreleasing作用看effective oc |
j)NSString 類型的屬性應該永遠聲明爲帶有copy attribute
這點是因爲NSString 的setters 永遠使用copy 而不是retain。NSString變量賦值給NSString之後,再改變賦值源並不會改變被賦值的變量;即實際實現是copy,所以一般NSString都用copy修飾比較一致;但如果賦值源是MutuableString時,用copy和用strong修飾NSString類型的變量還是有區別的,copy被賦值變量不會隨着賦值源改變而改變,但strong會。所以聲明成copy能保證不被影響。
block內存泄漏問題原理:
某個實例指向block,block中引用了該實例或該實例中的任意變量,均可能導致泄漏,必須改成weak引用。
內存警告處理:
多個app共享系統內存,前臺app內存不足時系統會殺其它掛起的app;低內存警告只會通知到running的app,掛起app不通知,直接殺掉;
注意點:
收到低內存警告的三個地方:
a)appdelegate applicationDidReceiveMemoryWarning:
b)UIViewController didReceiveMemoryWarning
c)註冊監聽通知事件:UIApplicationDidReceiveMemoryWarningNotification
收到低內存警告怎麼做:
a)釋放掉對緩存、圖片的強引用;
b)UIViewController的默認動作是將不可見的view移除;
c)一些後續仍可以正確初始化出來的數據可以清除掉;
減少內存使用的關鍵點:
a)杜絕內存泄漏;
b)減少資源文件尺寸:nib,png,plist等等;
c)對於大數據量存儲使用core data或sql lite;
d)資源文件懶加載;
e)包大小壓縮;thumb選項開啓可減少壓縮包大小,不過如果是浮點計算密集型應用可能效果不好;
f)僅加載需求的資源文件;
g)使用集合時必須考慮數據量大時是否有邊界?數據量大時的內存問題;
h)使用ARC;
2.響應時間:
a)耗時操作不要放在主線程中,易阻塞界面響應;
b)不要使用基於軟件的浮點運算數學函數庫,使用基於硬件的;
c)使用instrument工具進行調優,響應時間、電量、cpu及內存網絡等方面;
d)tableview的cell設置reuseIdentifier
e)圖片大小應與所顯示所需的一致或接近,resize很耗性能;
f)選取合適的集合類,dictionary適合按key存取,array利於隨機存取,但插刪特別慢;
g)能重複利用的靜態內容使用緩存;
h)使用繪製方式處理界面可使包更小,但耗時,直接帖圖片的方式快但打的包會變大,需要平衡;
i)NSDateFormatter和NSCalenda等對象初始化非常耗時的對象時,最好使用單例;
j)固定的常量要避免重複計算,比較單元格高度,一些初始化工作不要放在cellForRowAtIndexPath等;
k)啓動時間儘量快;
3.CPU:理論,問題,注意點;
cpu使用如果有問題第一是導致電量問題和發熱問題,發熱必然耗電;
cpu使用如果有問題第二是會影響響應時間;
4.電量:
理論:
ios通過關閉所有未正在使用中的硬件來省電;因此可從幾個方面來省電:cpu,地址位置,重力加速,磁盤,wifi與gprs等;
問題:
電量消耗過多問題比較明顯,就是使手機的續航能力弱;
注意點:
a)禁止使用輪詢方式,而使用定時器或NSLoop,減少CPU使用;
b)idleTimerDisabled設置爲NO,使一段時間未使用時屏幕可關閉;
c)將零散的工作一次性做掉(必要獲取的數據一次性獲取);
d)避免頻繁讀寫磁盤,比如一些數據寫入時,只有數據改變是寫入;
e)只在屏幕展示時才進行繪製計算相應的視圖;
f)重力加速感應與地理信息收集只在確實需要該功能時收集,地理信息時設置合適的距離與更新頻率很重要;
g)避免對外網絡請求一些不需要的數據,使用gzip壓縮;網絡請求很耗電量;手機網絡比wifi耗電;
h)網絡數據格式儘量簡短,如果自己可以定義協議的話;
i)一定要編寫處理網絡請求錯誤的方法,即使某些時候這些方法並不一定觸發;
5.UIWebView
前端性能優化必須要做的,若干種準則;UIWebview使用單例;使用進NSURLProtocol行緩存優化;
推薦文章:http://www.raywenderlich.com/59982/nsurlprotocol-tutorial
深度理解URL Loading System,使用其中的方式進行緩存優化,比如一些鐵定會訪問,但出現在Webview中的圖片圖標等可打包進app進行緩存,在URL訪問時,返回緩存的圖片以替代網絡請求;