最重要的: Xcode instruments
1、活用懶加載
重寫getter方法,不需要馬上用的對象不立即初始化,需要用到時才去初始化。
2、慎用autolayout
使用autolayout會隨著view的增多,其性能耗費也是越來越厲害。具體可以參考http://pilky.me/36/
3、慎用NSDateFormatter
其實我們都知道這個東西的初始化十分耗費性能,目前有兩個解決方案
(1)、使用單例,初始化一次
(2)、使用localTime,即將本地時間格式化成想要的格式
NSTimeInterval localTimeInterval = [[NSDate date] timeIntervalSince1970];
time_t timeInterval = (time_t)localTimeInterval;
struct tm * localTime = localtime(&timeInterval);
NSString * timeStr = [NSString stringWithFormat:@"%d %02d %02d %02d:%02d",localTime->tm_year + 1900,localTime->tm_mon + 1,localTime->tm_mday,localTime->tm_hour,localTime->tm_min];
NSLog(@"%@",timeStr);
//這是tm結構體的結構
struct tm {
int tm_sec; /* seconds after the minute [0-60] */
int tm_min; /* minutes after the hour [0-59] */
int tm_hour; /* hours since midnight [0-23] */
int tm_mday; /* day of the month [1-31] */
int tm_mon; /* months since January [0-11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday [0-6] */
int tm_yday; /* days since January 1 [0-365] */
int tm_isdst; /* Daylight Savings Time flag */
long tm_gmtoff; /* offset from CUT in seconds */
char *tm_zone; /* timezone abbreviation */
};
4、少用[NSString sizeWithAtteibutes:]
這貨也是一個比較吃性能的玩意兒,但是目前也沒有什么好的解決方案,可以異步計算字符串的長度再回調。CoreText也是個不錯的選擇,但是我不會??。
5、善用autoreleasepool
比如在一個for循環(huán)里加入@autoreleasepool{},在for循環(huán)里做操作,就能for循環(huán)里的內存降低很多,在大型循環(huán)里就有很大的用處了。
6、圖片加載機制
[UIImage imageWithContentsOfFile:@""];
[UIImage imageNamed:@""];
前者不緩存圖片 ,用完就釋放,適用于不常用的大圖,還有一點就是不能加載Asset Catelog里面的圖。
后者的使用會緩存圖片,適用于常使用的圖片,缺點也很明顯,就是會增加內存。
7、圖片解碼
當我們用UIimage或者CGImageSource的方法創(chuàng)建圖片時,圖片添加到UIImageView或者layer.contents后,圖片并不會立即被解碼,直到被提交到CPU的時候,才會被解碼,并且這個解碼過程是在主線程中執(zhí)行的。如果想要繞開這個機制,常見的做法是在后臺線程先把圖片繪制到 CGBitmapContext 中,然后從 Bitmap 直接創(chuàng)建圖片,目前常見的網絡圖片庫都自帶這個功能。 來自ibireme大神。
8、防止內存泄漏
這里就得最好使用instruments里的leaks工具,可以檢測到內存泄漏的地方。另外,Xcode8里新加了一個功能,叫做。。。我也不知道叫做什么,它長這個樣子
也可以很明顯地看到哪個地方有內存問題或是循環(huán)引用。
內存泄漏一般出現在block或者是delegate出現的地方,解除方法
@property(nonatomic,weak) id<MyDelegate> delegate;
/*注意,delegate可以使用assign和weak修飾,但是最好用weak修飾,因為在delegate釋放的時候,delegate將被置為nil,
防止了野指針的出現。但是自動置為nil也消耗一定的定能,需要注意一下。*/
__weak typeof(self) weakSelf = self;
/*解決block循環(huán)引用問題。也可以讓block的擁有者和引用者之間沒有引用關系,從根本上解決這個問題*/
//swift寫法
weak var delegate: MyDelegate
weak var weakSelf = self;
9、多張透明圖片混合
多個圖片疊加的時候,GPU會先將圖片混合到一起,所以盡量減少圖層的疊加,盡量將不透明的圖片的opaque設置為NO,避免無用的Alpha合成。
10、離屏渲染
在我們用layer的設置圓角或者是陰影的時候,往往會觸發(fā)離屏渲染,它發(fā)生在GPU內,如果在tableView里大量的使用layer的這些屬性,將會是幀率降得很低,形成明顯的卡頓。為了克服這些,啟用layer的shouldRasterize是個不錯的選擇,但是一定要避免作用在內容不斷變動的圖層上,否則它緩存方面的好處就會消失,而且會讓性能變的更糟。可以運用Core Animation工具里的Color HitsGreen和Misses Red選項,看shouldRasterize的運用是否合理。后臺線程中繪制圓角圖可以從根本上解決這個問題,或者說可以直接讓設計師設計個圓角蓋子(這才是真正的解決??)。
11、tableView的提前布局計算
在tableView里往往需要自適應高度,拿到數據,在子線程中計算cell的布局是有必要的,可以封裝一個布局model。盡量不要在變化的cell里使用autolayout,如果允許,多用layer層級的東西,比如CAShapeLayer,CATextLayer等。
對性能要求不高的可以使用iOS新出的預估計cell高度的方法。
12、。。。
參考:
Core Animation: Advanced Techniques
2016 MDCC 搜狗輸入法性能優(yōu)化實踐
http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/