iOS-性能優化的那些事

前言

本人在這家公司已經三年多了,這款三年多我一直在做的APP也爛熟於心,APP也0到1到目前的500萬的用戶量;對於APP的功能來說也是比較全面的,用到的技術知識點也比較多吧,APP的優化也是一直在做的事情,而且APP性能的優化也不是一朝一夕的事情,在此離別之際,我將詳細說明講解一下我在三年裏對APP性能優化方面做過的一些事,大家仁者見仁智者見智,也歡迎大家進羣提供寶貴的意見和建議!

這裏我主要講性能方面的優化,代碼方面的優化或者說API包方面的優化請看我的另一篇博文:

? iOS-APP包的瘦身之旅(從116M到現在的36M的減肥之路)?

基礎優化

使用ARC,現在的iOS開發大家用的都是ARC,幾乎沒有人再去使用MRC了,使用ARC的好處就是不用再時時刻刻注意要釋放創建的對象了;避免使用xib或者storyboard。

這裏說一下xib和sb的缺點吧,如下:

1.佔用API包比較大;

2.導致APP啓動時間比較耗時,因爲在APP啓動main()以前需要加載他們;

3.加載速度比較慢;

4.後期的版本更新迭代維護時間成本比較高;

5.多人開發容易引起衝突。

列表圖片優化

列表不論在哪一個APP中是使用最爲廣泛的一款控件了,在我的APP中也不例外,我們的APP只要功能列表類似於微信的朋友圈,圖片有0~9張的形式還可以是視頻文件,如下圖:

先說一說圖片吧,如果一個列表都是9張圖片,列表在加載和滑動的時候會耗用過多的內存;我在這裏是把圖片這一塊單獨抽出來做一個圖片資源的封裝,然後根據創建的圖片容器(UIImageView)的大小加載縮略圖,我們公司的APP存儲用的是七牛雲存儲,所以在獲取圖片資源的時候,只需要設置對應的字段就可以拿到縮略圖了,點擊的查看大圖的時候才查看原圖;

再說說視頻,視頻的處理邏輯和圖片差不多,這裏在CELL上我們使用一個UIImageView來替代視頻播放器,可以去出視頻的第一幀作爲封面,點擊圖片的時候才調用我們封裝好的視頻播放組件。

複用機制

說道複用,我們可能常用的有CELL的複用,其實我們也可以自己寫我們的服用,就比如上圖中的列表,我們一般採用的思路就是在主控制器上添加一個UIScrollView,再根據有多少個小標題類型創建多少個子控制器,接着把子控制器添加到主控制器的childViewControllers中,最後把子控制器的視圖添加到UIScrollView上,有沒有更節省內存空間的做法呢???

當然有的,我們可以只創建5個控制器然後丟到我們的可重用數組中,根據每次滑動去加載不同的緩存數據;

還比如我在直播間創建刷禮物的視圖動畫的時候,因爲最多隻能顯示三條,那麼我只會創建三個視圖,當有大於三條的禮物信息過來的時候也只會創建三個視圖,然後丟進我的可重用數組裏面,每個視圖動畫完成以後才重新複製Model,如下圖左下角的禮物動畫最多三個,最少沒有:

就如上面所說,在項目中我們可以在很多地方創建屬於我們自己的重用機制!

離屏渲染

在開發中,我們常用有圓角處理、陰影、遮罩等等;先說說圓角優化吧,我們一般設置圓角的方式如下:

view.layer.cornerRadius = 10;
view.layer.masksToBounds = YES;

這樣處理的渲染機制是GPU在當前屏幕緩衝區外新開闢一個渲染緩衝區進行工作,也就是離屏渲染,這會給我們帶來額外的性能損耗,如果這樣的圓角操作達到一定數量,會觸發緩衝區的頻繁合併和上下文的的頻繁切換,性能的代價會宏觀地表現在用戶體驗上——掉幀。

優化方案:

a.可以做一個透明的png圖片蓋在上面;

b.使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角;

c.使用CAShapeLayer和UIBezierPath設置圓角;

d.也可以將圖片的處理放在服務端(比如:七牛雲儲存就可以設置圖片的圓角);

e.儘量把view設置成不透明的。

說明:離屏渲染還可以做很多東西,具體的可以自行查找!

懶加載

這裏的懶加載主要說的是懶加載思想,可以懶加載的類型有很多,當然好處有很多,最主要的是可以節省內存資源;

重大開銷對象

我們在APP使用過程中會用到很多重大開銷對象(比如NSDateFormatter和 NSCalendar),如我們在列表需要計算用戶年齡的時候會經常用到NSDateFormatter,還有一些時間的格式化輸出,或者在網絡請求的時候需要傳一些時間戳,所以我們可以把NSDateFormatter放在單利裏面,這樣就不用經常創建了,其他的也是同樣的道理。

還有就是,像年齡生日什麼的最好不要由前端APP來計算,最好放在服務器上,由服務端計算好然後再傳給我們。

內存警告

如果程序在運行過程中發生了內存警告(didReceiveMemoryWarning),我們需要快速應急處理一下,不要用不了多久APP就會被殺死掉,所在在收到內存警告主要思路就是想着去清理棧上的東西,以後我們可以做以下幾點:

a.清理不需要的已經創建的對象,不論是試圖還是工具類;

b.釋放單利裏面不需要的對象,比如上文提高過得重大開銷對象;

c.如果有正在下載的任務,取消或者暫停全部任務;

d.如果使用了SDWebImage,可以清理一下緩存clearMemory;

主線程流暢

不要阻塞主線程,要保證主線程的流程性;我們不要把一些重大開銷對象放到主線程裏面,我們可以創建子線程去處理這些事情;比如多個網絡請求結束一起刷新UI、多個動畫效果、數據的讀寫操作等等;

數據緩存

做緩存這個事情,一方面減小內存的小號,還有很重要的一方面就是優化用戶體驗;可以做緩存的東西很多,我們可以對數據接口進行緩存,還可以對WebView進行緩存,還有圖片緩存、高度緩存等等;

在這裏不得不說一下,數據存儲了;我們在做緩存的時候選擇正確合適的存儲方式也很難重要,當然大家也可以根據項目的實際需求來選擇存儲,我們公司的APP本地存儲我選擇的是SQLite,管理類是我基於FMDB的又一次封裝,相信請參考:

?《iOS-基於FMDB的操作封裝,模型對象的增刪改查》?

https://blog.csdn.net/u014220518/article/details/78189927

網絡API優化

這個優化不單單需是前端小夥伴的事,還需要後端開發人員的配合,避免一些不必要數據的返回,更要避免在APP端處理或者計算太多東西,比如年齡、星座的計算;即使後端的小夥伴把一些不必要的數據返回了,我們在創建數據模型Model的時候可以選擇不去接收!

PS:這裏我需要吐槽一下,以前公司有個java後端,返回的數據全部是一個表的實體類,管你有用沒用,直接一股腦的全給你,自己去計算和自己去查找,那真叫一個心累啊,所以一個優秀的API開發工程師也是一個非常重要的原因!

自動釋放池

自動釋放池(autoreleasepool)在MRC的時代真是用的非常多,但是現在的項目都是ARC,自動釋放池用的也就比較少了,因爲有系統幫我們監管,但是如果我們一個頁面創建了太多的類或者對象,如果等頁面銷燬的時候由系統統一釋放難免會出現一個峯值影響整體性能,這時候我們就可以考慮使用autoreleasepool了,避免峯值的出現!?

還比如我們在遍歷一些大數組或者字典的時候,可以使用自動釋放池來降低內存峯值,比如:

NSArray *bigArray = @[] //這是一個很大很大的數組
NSMutableArray *newArray = [[NSMutableArray alloc] init];
for (NSStirng *item in bigArray) {
    @autoreleasepool {
        ZFJModel *model = [[ZFJModel alloc] init];
        model.item = item;
        [newArray addObject: model];
    }
}

APP啓動優化

在AppDelegate裏面我們會寫一些很多東西,你寫的東西越多越影響APP的冷啓動時間就會越長,因此我們需要對AppDelegate進行減負,具體如何減負大家可以根據各自項目的實際情況,第一可以刪除一些不是必須的東西;第二可以把一些東西寫在別的地方(如RootViewController),我在APP的RootViewController寫的東西比如IM聊天的配置初始化登錄,一些未處理的任務,還有一些版本的堅持和緩存的清理等等!

Instruments

Instruments 是什麼我這裏就不作過多的介紹了,這裏我主要說我用Instruments幹什麼;我平時用Instruments主要幹兩件事,一件事是檢查內存泄漏,還有一件事是檢查耗時函數;對於內存泄漏我們對應修改補漏就行了,對於耗時函數要麼就換一種寫法,要麼就創建一個子線程來處理!

?這裏要說一個我的習慣,我的所有的控制器都繼承於BaseViewController,然後我再BaseViewController裏面寫了以下的一部分代碼:

- (void)dealloc{
    NSLog(@"=== %@ dealloced! ===", NSStringFromClass([self class]));
}

如果我的頁面銷燬不走dealloc的打印,那麼頁面肯定有沒有被釋放的對象,要麼是發生循環引用了,要麼是需要手動釋放,具體打印以下對象的引用計數

結束語

歡迎各位大神補充和糾正,也歡迎大家進羣交流學習!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章