一:內(nèi)存管理的理解
首先iOS中數(shù)據(jù)是存貯在堆和棧中的。內(nèi)存管理需要管理堆上的內(nèi)存,棧上的內(nèi)存并不需要我們管理。
非OC對象(基礎(chǔ)數(shù)據(jù)類型)存儲在棧上
OC對象存儲在堆上。
iOS內(nèi)存管理是靠引用計數(shù)技術(shù)來實(shí)現(xiàn)的。當(dāng)創(chuàng)建一個對象引用計數(shù)增加1.當(dāng)引用計數(shù)未0的時候內(nèi)存就會被釋放。
在很久之前使用手動釋放機(jī)制,誰創(chuàng)建誰負(fù)責(zé)釋放?,F(xiàn)在使用的是自動釋放管理。ARC。會根據(jù)引用計數(shù)自動監(jiān)視對象的生存周期,實(shí)現(xiàn)方式是在編譯時期自動在已有代碼中插入合適的內(nèi)存管理代碼x,像retain、release、copy、autorelease、autoreleasepool以及在Runtime做一些優(yōu)化。
對于__strong表示強(qiáng)引用。
__weak 表示弱引用。他不會影響對象的釋放,而當(dāng)對象釋放的時候,所有指向它的弱引用都會自定義被置為nil,這樣可以防止野指針。
使用場景
在Delegate關(guān)系中防止循環(huán)引用
在Block中防止循環(huán)引用,
用來修飾指向由Interface Builder 創(chuàng)建的控件。
對象通過objc_release釋放對象內(nèi)存的動作。
objc_release
因?yàn)橐糜嫈?shù)為0所以執(zhí)行dealloc
_objc_rootDealloc
objc_dispose
objc_destructInstance
objc_clear_deallocating
二:循環(huán)引用的理解
循環(huán)引用就是在兩個對象之間強(qiáng)引用了,引用計數(shù)都加1了,只有當(dāng)引用計數(shù)減為0時對象才釋放,但是這兩個的引用計數(shù)都依賴對方,所以就導(dǎo)致永遠(yuǎn)無法釋放。
使用weakSelf打破死循環(huán)的狀態(tài),被__weak修飾的對象,會隨著它的strong對象置空而自動置空,同時不會引起引用計數(shù)的變化。
在block體里繼續(xù)轉(zhuǎn)換出strongself為了避免當(dāng)self被dealloc函數(shù)體中weakSelf = nil的情況出現(xiàn)。再次調(diào)用會引起閃退。
三:UItableView的優(yōu)化
1:CPU減輕負(fù)荷
1)提前計算好高度,緩存在相應(yīng)的數(shù)據(jù)源模型中
2)盡可能降低storyboard,xib等使用
3)滑動過程中盡量避免重新布局
- 復(fù)用cell,header,footer
- 圖片不過大,壓縮尺寸后顯示。
6)避免大量對layer的操作。盡量設(shè)置圖片為不透明。
7)謹(jǐn)慎使用drawRect方法。
2:不要阻塞主線程
1)避免快速華東的情況下開過多的線程。
線程開過多了會造成資源浪費(fèi),內(nèi)存開銷過大。圖片過多時可以不要一滾動就走cellForRow方法,可以在scrollview的代理方法中做限制,當(dāng)滾動開始減速的時候才加載顯示在當(dāng)前屏幕上的cell(通過tableview的dragging和declearating兩個狀態(tài)也能判斷)
圖片處理
2)后臺下載圖片后再回主線程刷新UI,避免阻塞主線程。
簡單的設(shè)置cornerRadius是不會影響性能的,但是設(shè)置了maskToBounds,會導(dǎo)致離屏渲染,應(yīng)減少設(shè)置圖層 maskToBounds = YES ,;
使用懶加載圖片的方式避免重復(fù)下載圖片,浪費(fèi)資源。圖片下載后并做壓縮處理后將其保存到緩存中,下次加載此圖片之前先從緩存中取,如果取不到該圖片就在后臺下載保存。
使用Core Graphics實(shí)現(xiàn)圓角等功能。
重寫drawRect方法會離屏渲染,導(dǎo)致內(nèi)存急劇上升,即使在這個方法里面不寫一句代碼,也會讓內(nèi)存升高。