iOS面試題:簡述性能優化

在性能優化中一個最具參考價值的屬性是FPS:Frames Per Second,其實就是屏幕刷新率,蘋果的iphone推薦的刷新率是60Hz,也就是說GPU每秒鐘刷新屏幕60次,這每刷新一次就是一幀frame,FPS也就是每秒鐘刷新多少幀畫面。靜止不變的頁面FPS值是0,這個值是沒有參考意義的,只有當頁面在執行動畫或者滑動的時候,FPS值才具備參考價值,FPS值的大小體現了頁面的流暢程度高低,當低於45的時候卡頓會比較明顯。javascript

圖層混合:java

每個layer是一個紋理,全部的紋理都以某種方式堆疊在彼此的頂部。對於屏幕上的每個像素,GPU須要算出怎麼混合這些紋理來獲得像素RGB的值。web

當Sa = 0.5時,RGB值爲(0.5, 0, 0),能夠看出,當兩個不是徹底不透明的CALayer覆蓋在一塊兒時,GPU大量作這種複合操做,隨着這中操做的越多,GPU越忙碌,性能確定會受到影響。面試

公式:數據庫

R = S + D * ( 1 – Sa )編程

結果的顏色是源色彩(頂端紋理)+目標顏色(低一層的紋理)*(1-源顏色的透明度)。json

當Sa = 1時,R = S,GPU將不會作任何合成,而是簡單從這個層拷貝,不須要考慮它下方的任何東西(由於都被它遮擋住了),這節省了GPU至關大的工做量。緩存

1、入門級

一、用ARC管理內存
二、在正確的地方使用 reuseIdentifier
三、儘可能把views設置爲透明
四、避免過於龐大的XIB
五、不要阻塞主線程性能優化

六、在ImageViews中調整圖片大小。若是要在UIImageView中顯示一個來自bundle的圖片,你應保證圖片的大小和UIImageView的大小相同。在運行中縮放圖片是很耗費資源的,特別是UIImageView嵌套在UIScrollView中的狀況下。若是圖片是從遠端服務加載的你不能控制圖片大小,好比在下載前調整到合適大小的話,你能夠在下載完成後,最好是用background
thread,縮放一次,而後在UIImageView中使用縮放後的圖片。服務器

七、選擇正確的Collection。

  • Arrays: 有序的一組值。使用index來lookup很快,使用value lookup很慢, 插入/刪除很慢。
  • Dictionaries: 存儲鍵值對。 用鍵來查找比較快。
  • Sets: 無序的一組值。用值來查找很快,插入/刪除很快。

八、打開gzip壓縮。app可能大量依賴於服務器資源,問題是咱們的目標是移動設備,所以你就不能期望網絡情況有多好。減少文檔的一個方式就是在服務端和你的app中打開gzip。這對於文字這種能有更高壓縮率的數據來講會有更顯著的效用。
iOS已經在NSURLConnection中默認支持了gzip壓縮,固然AFNetworking這些基於它的框架亦然。

2、中級

一、重用和延遲加載(lazy load) Views

  • 更多的view意味着更多的渲染,也就是更多的CPU和內存消耗,對於那種嵌套了不少view在UIScrollView裏邊的app更是如此。
  • 這裏咱們用到的技巧就是模仿UITableView和UICollectionView的操做: 不要一次建立全部的subview,而是當須要時才建立,當它們完成了使命,把他們放進一個可重用的隊列中。這樣的話你就只須要在滾動發生時建立你的views,避免了不划算的內存分配。

二、Cache, Cache, 仍是Cache!

  • 一個極好的原則就是,緩存所須要的,也就是那些不大可能改變可是須要常常讀取的東西。
  • 咱們能緩存些什麼呢?一些選項是,遠端服務器的響應,圖片,甚至計算結果,好比UITableView的行高。
  • NSCache和NSDictionary相似,不一樣的是系統回收內存的時候它會自動刪掉它的內容。

三、權衡渲染方法.性能能仍是要bundle保持合適的大小。

四、處理內存警告.移除對緩存,圖片object和其餘一些能夠重建立的objects的strong references.

五、重用大開銷對象

六、一些objects的初始化很慢,好比NSDateFormatter和NSCalendar。然而,你又不可避免地須要使用它們,好比從JSON或者XML中解析數據。想要避免使用這個對象的瓶頸你就須要重用他們,能夠經過添加屬性到你的class裏或者建立靜態變量來實現。

七、避免反覆處理數據.在服務器端和客戶端使用相同的數據結構很重要。

八、選擇正確的數據格式.解析JSON會比XML更快一些,JSON也一般更小更便於傳輸。從iOS5起有了官方內建的JSON deserialization 就更加方便使用了。可是XML也有XML的好處,好比使用SAX 來解析XML就像解析本地文件同樣,你不需像解析json同樣等到整個文檔下載完成纔開始解析。當你處理很大的數據的時候就會極大地減低內存消耗和增長性能。

九、正確設定背景圖片

  • 全屏背景圖,在view中添加一個UIImageView做爲一個子View
  • 只是某個小的view的背景圖,你就須要用UIColor的colorWithPatternImage來作了,它會更快地渲染也不會花費不少內存:

十、減小使用Web特性。想要更高的性能你就要調整下你的HTML了。第一件要作的事就是儘量移除沒必要要的javascript,避免使用過大的框架。能只用原生js就更好了。儘量異步加載例如用戶行爲統計script這種不影響頁面表達的javascript。注意你使用的圖片,保證圖片的符合你使用的大小。

十一、Shadow Path 。CoreAnimation不得不先在後臺得出你的圖形並加好陰影而後才渲染,這開銷是很大的。使用shadowPath的話就避免了這個問題。使用shadow path的話iOS就沒必要每次都計算如何渲染,它使用一個預先計算好的路徑。但問題是本身計算path的話可能在某些View中比較困難,且每當view的frame變化的時候你都須要去update shadow path.

十二、優化Table View

  • 正確使用reuseIdentifier來重用cells
  • 儘可能使全部的view opaque,包括cell自身
  • 避免漸變,圖片縮放,後臺選人
  • 緩存行高
  • 若是cell內現實的內容來自web,使用異步加載,緩存請求結果
  • 使用shadowPath來畫陰影
  • 減小subviews的數量
  • 儘可能不適用cellForRowAtIndexPath:,若是你須要用到它,只用-一次而後緩存結果
  • 使用正確的數據結構來存儲數據
  • 使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight來設定固定的高,不要請求delegate

1三、選擇正確的數據存儲選項

  • NSUserDefaults的問題是什麼?雖然它很nice也很便捷,可是它只適用於小數據,好比一些簡單的布爾型的設置選項,再大點你就要考慮其它方式了
  • XML這種結構化檔案呢?整體來講,你須要讀取整個文件到內存裏去解析,這樣是很不經濟的。使用SAX又是一個很麻煩的事情。
  • NSCoding?不幸的是,它也須要讀寫文件,因此也有以上問題。
  • 在這種應用場景下,使用SQLite 或者 Core Data比較好。使用這些技術你用特定的查詢語句就能只加載你須要的對象。
  • 在性能層面來說,SQLite和Core Data是很類似的。他們的不一樣在於具體使用方法。
  • Core Data表明一個對象的graph model,但SQLite就是一個DBMS。
  • Apple在通常狀況下建議使用Core Data,可是若是你有理由不使用它,那麼就去使用更加底層的SQLite吧。
  • 若是你使用SQLite,你能夠用FMDB這個庫來簡化SQLite的操做,這樣你就不用花不少經歷瞭解SQLite的C API了。

3、高級

一、加速啓動時間。快速打開app是很重要的,特別是用戶第一次打開它時,對app來說,第一印象太太過重要了。你能作的就是使它儘量作更多的異步任務,好比加載遠端或者數據庫數據,解析數據。避免過於龐大的XIB,由於他們是在主線程上加載的。因此儘可能使用沒有這個問題的Storyboards吧!必定要把設備從Xcode斷開來測試啓動速度

二、使用Autorelease Pool。NSAutoreleasePool`負責釋放block中的autoreleased objects。通常狀況下它會自動被UIKit調用。可是有些情況下你也須要手動去建立它。假如你建立不少臨時對象,你會發現內存一直在減小直到這些對象被release的時候。這是由於只有當UIKit用光了autorelease pool的時候memory纔會被釋放。消息是你能夠在你本身的@autoreleasepool裏建立臨時的對象來避免這個行爲。

三、選擇是否緩存圖片。常見的從bundle中加載圖片的方式有兩種,一個是用imageNamed,二是用imageWithContentsOfFile,第一種比較常見一點。

四、避免日期格式轉換。若是你要用NSDateFormatter來處理不少日期格式,應該當心以待。就像先前提到的,任什麼時候候重用NSDateFormatters都是一個好的實踐。若是你能夠控制你所處理的日期格式,儘可能選擇Unix時間戳。你能夠方便地從時間戳轉換到NSDate:

- (NSDate*)dateFromUnixTimestamp:(NSTimeInterval)timestamp {
    return[NSDate dateWithTimeIntervalSince1970:timestamp];
    }

這樣會比用C來解析日期字符串還快!須要注意的是,許多web API會以微秒的形式返回時間戳,由於這種格式在javascript中更方便使用。記住用dateFromUnixTimestamp以前除以1000就行了。

平時你是如何對代碼進行性能優化的?

  • 利用性能分析工具檢測,包括靜態 Analyze 工具,以及運行時 Profile 工具,經過Xcode工具欄中Product->Profile能夠啓動,
  • 好比測試程序啓動運行時間,當點擊Time Profiler應用程序開始運行後.就能獲取到整個應用程序運行消耗時間分佈和百分比.爲了保證數據分析在統一使用場景真實須要注意必定要使用真機,由於此時模擬器是運行在Mac上,而Mac上的CPU每每比iOS設備要快。
  • 爲了防止一個應用佔用過多的系統資源,開發iOS的蘋果工程師門設計了一個「看門狗」的機制。在不一樣的場景下,「看門狗」會監測應用的性能。若是超出了該場景所規定的運行時間,「看門狗」就會強制終結這個應用的進程。開發者們在crashlog裏面,會看到諸如0x8badf00d這樣的錯誤代碼。

優化Table View

  • 正確使用reuseIdentifier來重用cells
  • 儘可能使全部的view opaque,包括cell自身
  • 若是cell內現實的內容來自web,使用異步加載,緩存請求結果
    減小subviews的數量
  • 儘可能不適用cellForRowAtIndexPath:,若是你須要用到它,只用一次而後緩存結果
  • 使用rowHeight, sectionFooterHeight和sectionHeaderHeight來設定固定的高,不要請求delegate

UIImage加載圖片性能問題

  • imagedNamed初始化
  • imageWithContentsOfFile初始化
  • imageNamed默認加載圖片成功後會內存中緩存圖片,這個方法用一個指定的名字在系統緩存中查找並返回一個圖片對象.若是緩存中沒有找到相應的圖片對象,則從指定地方加載圖片而後緩存對象,並返回這個圖片對象.
  • imageWithContentsOfFile則僅只加載圖片,不緩存.
  • 加載一張大圖而且使用一次,用imageWithContentsOfFile是最好,這樣CPU不須要作緩存節約時間.
  • 使用場景須要編程時,應該根據實際應用場景加以區分,UIimage雖小,但使用元素較多問題會有所凸顯.

    • 不要在viewWillAppear 中作費時的操做:viewWillAppear: 在view顯示以前被調用,出於效率考慮,方法中不要處理複雜費時操做;在該方法設置 view 的顯示屬性之類的簡單事情,好比背景色,字體等。不然,會明顯感受到 view 有卡頓或者延遲。
    • 在正確的地方使用reuseIdentifier:table view用 tableView:cellForRowAtIndexPath:爲rows分配cells的時候,它的數據應該重用自UITableViewCell。
    • 儘可能把views設置爲透明:若是你有透明的Views你應該設置它們的opaque屬性爲YES。系統用一個最優的方式渲染這些views。這個簡單的屬性在IB或者代碼裏均可以設定。
    • 避免過於龐大的XIB:儘可能簡單的爲每一個Controller配置一個單獨的XIB,儘量把一個View Controller的view層次結構分散到單獨的XIB中去, 當你加載一個引用了圖片或者聲音資源的nib時,nib加載代碼會把圖片和聲音文件寫進內存。
    • 不要阻塞主線程:永遠不要使主線程承擔過多。由於UIKit在主線程上作全部工做,渲染,管理觸摸反應,迴應輸入等都須要在它上面完成,大部分阻礙主進程的情形是你的app在作一些牽涉到讀寫外部資源的I/O操做,好比存儲或者網絡。
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      // 選擇一個子線程來執行耗時操做
      dispatch_async(dispatch_get_main_queue(), ^{
      // 返回主線程更新UI
      });
      });
    • 在Image Views中調整圖片大小
      若是要在UIImageView中顯示一個來自bundle的圖片,你應保證圖片的大小和UIImageView的大小相同。在運行中縮放圖片是很耗費資源的.

講講你用Instrument優化動畫性能的經歷吧(別問我什麼是Instrument)

Apple的instrument爲開發者提供了各類template去優化app性能和定位問題。不少公司都在趕feature,並無充足的時間來作優化,致使很多開發者對instrument不怎麼熟悉。但這裏面其實涵蓋了很是完整的計算機基礎理論知識體系,memory,disk,network,thread,cpu,gpu等等,順藤摸瓜去學習,是一筆巨大的知識財富。動畫性能只是其中一個template,重點仍是理解上面問題當中CPU GPU如何配合工做的知識。

facebook啓動時間優化

1.瘦身請求依賴
2.UDP啓動請求先行緩存
3.隊列串行化處理啓動響應


更多:iOS面試題答案合集

另外附上一份各個好友收集的各大廠面試題+答案 ! 須要的可加 iOS技術探討羣:624212887,羣文件直接獲取

以下圖所示:

相關文章
相關標籤/搜索