面了20多家總結出來的部分iOS面試題(五)

27. SDWebImage是怎么做緩存的?

  • 首先說,緩存采用了二級 緩存策略。 圖片緩存的時候, 在內存有緩存, 在磁盤中也有緩存, 其中內存緩存是用NSCache做的 (下面會有NSCache的說明)。
    一、如何做緩存的步驟:
    0、下載圖片
    1、將圖片緩存在內存中
    2、判斷圖片的格式png或jpeg,將圖片轉成NSData數據
    3、獲取圖片的存儲路徑, 其中圖片的文件名是通過傳入Key經過MD5加密后獲得的
    4、將圖片存在進磁盤中。

二、如何獲取圖片的?
1、在內存緩存中找
2、如果內存中找不到, 會去默認磁盤目錄中尋找, 如果找不到,在去自定義磁盤目錄中尋找
3、如果磁盤也找不到就會下載圖片
4、獲取圖片數據之后, 將圖片數據從NSData轉化UIImage。其中轉化根據圖片的類型進行轉化
5、默認對圖片進行解壓縮,生成位圖圖片
6、將位圖圖片返回

三、圖片是如何被解壓縮的?
1、判斷圖片是否是動態圖片,如果是,不能解壓縮
2、判斷圖片是否透明,如果是,不能解壓縮
3、判斷圖片的顏色空間是不是RGB如果不是、不能解壓縮
4、根據圖片的大小創建一個上下文
5、將圖片繪制在上下文中
6、從上下文中讀取一個不透明的位圖圖像,該圖像就是解壓縮后的圖像
7、將位圖圖像返回

接上說 NSCache

  • 這個NSCache說白了就是做緩存專用的一個系統類
  • 類似可變字典一樣,但是NSCache是線程安全的, 系統類自動做好了加鎖和釋放鎖等一系列的操作, 還有一個重要的是如果內存不足的時候NSCache會自動釋放掉存儲的對象,不需要開發者手動干預。
  • 來看一眼NSCache提供的屬性和相關方法
//名稱
@property (copy) NSString *name;

//NSCacheDelegate代理
@property (nullable, assign) id<NSCacheDelegate> delegate;

//通過key獲取value,類似于字典中通過key取value的操作
- (nullable ObjectType)objectForKey:(KeyType)key;

//設置key、value
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; // 0 cost

/*
設置key、value
cost表示obj這個value對象的占用的消耗?可以自行設置每個需要添加進緩存的對象的cost值
這個值與后面的totalCostLimit對應,如果添加進緩存的cost總值大于totalCostLimit就會自動進行刪除
感覺在實際開發中直接使用setObject:forKey:方法就可以解決問題了
*/
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;

//根據key刪除value對象
- (void)removeObjectForKey:(KeyType)key;

//刪除保存的所有的key-value
- (void)removeAllObjects;

/*
當NSCache緩存的對象的總cost值大于這個值則會自動釋放一部分對象直到占用小于該值
非嚴格限制意味著如果保存的對象超出這個大小也不一定會被刪除
這個值就是與前面setObject:forKey:cost:方法對應
*/
@property NSUInteger totalCostLimit;    // limits are imprecise/not strict

/*
緩存能夠保存的key-value個數的最大數量
當保存的數量大于該值就會被自動釋放
非嚴格限制意味著如果超出了這個數量也不一定會被刪除
*/
@property NSUInteger countLimit;    // limits are imprecise/not strict
/*
這個值與NSDiscardableContent協議有關,默認為YES
當一個類實現了該協議,并且這個類的對象不再被使用時意味著可以被釋放
*/
@property BOOL evictsObjectsWithDiscardedContent;

@end

//NSCacheDelegate協議
@protocol NSCacheDelegate <NSObject>
@optional
//上述協議只有這一個方法,緩存中的一個對象即將被刪除時被回調
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
@end**

countLimit注意一下這個屬性, 這個屬性就是設置最大緩存數量,啥意思呢? 這玩意就和棧差不多, 先進先出(叫什么FIFO?)原則。比如你countLimit設置為5 那么當你緩存第6個對象的時候, 原本第一個就被移除了。 所以這便就有有一個風險,也可能會是面試點,為什么,通過key去取值的時候,一定要判斷一個獲取的對象是否為nil?答:就因為很有可能某些對象被釋放(頂)掉了。

又又又可能出現的面試題!NSCache里面緩存的對象,在什么場景下會被釋放?

  • 回答之前,先說一情況,在某C中創建了NSCache對象,點擊手機的Home或者任何方式進入后臺,會發現NSCache中的代理方法被執行了,于是NSCache對象會釋放掉所有對象,還有的是,如果發生內存警告也會釋放掉所有對象。所以, 這道題應該如下這么回答!
  • NSCache自身釋放了,其中存儲的對象也就釋放了。
  • 手動調用釋放方法removeObjectForKey、removeAllObjects
  • 緩存對象個數大于countLimit
  • 緩存總消耗大于totalCostLimit
  • 程序進入后臺
  • 收到內存警告

28.SDWebImage實現原理是什么? 它是如何解決tableView的復用時出現圖片錯亂問題的呢

  • 原理如上,
  • 錯亂是在UIImageView+WebCache文件中這個方法每次都會調用 [self sd_cancelCurrentImageLoad];

29. 為什么刷新UI要在主線程操作

  • UIKit并不是一個線程安全的類,所以涉及多個線程同時對UI進行操作會造成影響。

  • 為什么不把UIKit框架設置為線程安全呢?

  • 因為線程安全需要加鎖,我們都知道加鎖就會消耗性能,影響處理速度,影響渲染速度,我們通常自己在寫@property時都會寫nonatomic來追求高性能高效率。

  • 假設能夠異步設置view的屬性,那我們究竟是希望這些改動能夠同時生效,還是按照各自runloop的進度去改變這個view的屬性呢?

  • 假設UITableView在其他線程去移除了一個cell,而在另一個線程卻對這個cell所在的index進行一些操作,這時候可能就會引發crash。

  • 如果在后臺線程移除了一個view,這個時候runloop周期還沒有完結,用戶在主線程點擊了這個“將要”消失的view,那么究竟該不該響應事件?在哪條線程進行響應?

  • 在Cocoa Touch框架中,UIApplication初始化工作是在主線程進行的。而界面上所有的視圖都是在UIApplication 實例的葉子節點(內存管理角度),所以所有的手勢交互操作都是在主線程上才能響應

30. RunTime

類的結構體:

//Class也表示一個結構體指針的類型
typedef struct objc_class *Class;

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

分類結構體

struct category_t {
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods; // 對象方法
    struct method_list_t *classMethods; // 類方法
    struct protocol_list_t *protocols; // 協議
    struct property_list_t *instanceProperties; // 屬性
    // Fields below this point are not always present on disk.
    struct property_list_t *_classProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};

引申1. class_copyIvarList與class_copyPropertyList的區別?

  • 1.class_copyIvarList:能夠獲取.h和.m中的所有屬性以及大括號中聲明的變量,獲取的屬性名稱有下劃線(大括號中的除外)。
  • 2.class_copyPropertyList:只能獲取由property聲明的屬性,包括.m中的,獲取的屬性名稱不帶下劃線。

引申2. class_ro_t和class_rw_t的區別?

  • class_rw_t提供了運行時對類拓展的能力,
  • class_ro_t存儲的大多是類在編譯時就已經確定的信息。
  • 二者都存有類的方法、屬性(成員變量)、協議等信息,不過存儲它們的列表實現方式不同。簡單的說class_rw_t存儲列表使用的二維數組,class_ro_t使用的一維數組。
  • class_ro_t存儲于class_rw_t結構體中,是不可改變的。保存著類的在編譯時就已經確定的信息。
  • 運行時修改類的方法,屬性,協議等都存儲于class_rw_t中

31. NSNotification

  • NSNotificationCent 子線程中發出通知,也要在主線程中刷新UI
// 比如
   dispatch_async(dispatch_get_main_queue(), ^{
       // 刷新UI
   });
  • NSNotificationCenter用完之后不移除, 會崩潰么?
  • 有時候會導致crash。比如在通知事件中處理數據或者UI事件,但是由于通知的不確定性造成事件的不確定,有異步操作在通知事件中處理等都可能造成崩潰。
  • 而且通知的崩潰很難檢測。

32. 什么情況使用 weak 關鍵字,相比 assign 有什么不同?(輪回系列)

  • weak 這個詞兒解決了一件事情,就是內存的事情
  • 在ARC中weak的出現解決了一些循環引用的問題, 比如delegate, xib連線出來的控件一般也是weak(也可以用strong )
  • weak表明了一種“非擁有的關系”,不保留新值,也不釋放舊值。
  • assign也是如此,但常用的assign一般用于基本數據類型(CGFloat 或 NSlnteger等)
  • assign可以用于非OC對象,也可以用于OC對象(MRC時代使用), 但是weak必須用在OC對象。

引申 1.關鍵字copy 的用法?

  • block用Copy是MRC時代留下來的傳統。在MRC中方法內部的block是在棧區的, 使用copy可以把它放到堆區。 在ARC中寫不寫都行,用Strong也是可以的。
  • NSString、NSArray、NSDictionary也經常使用copy, 因為里面有對應的可變的子類型,為了確保安全性, 建議使用copy修飾

引申 2.@property 的本質是什么?ivar、getter、setter 是如何生成并添加到這個類中的。

  • @property = ivar(實例變量) + getter + setter
  • 自動合成

33. 說說內存管理?

  • 其實遇到這道題,挺糾結的,有些TMD面試官就是習慣搞人,從這個玩意里面 能往死給你嗑! 你要看過相關內存管理的詳細原理,你會發現這里面的C++操作很多,沒學過C++的人能看個八九不離十,可是也只是能說個大其概,但是內部細節還是得用C++來說,廢話不多說, 直接上說所謂得面試答案。
  • 粗糙版本這么回答
  • 版本一: 內存中每一個對象都有一個屬于自己的引用計數器。當某個對象A被另一個對象引用時,A的引用計數器就+1,如果再有一個對象引用到A,那么A的引用計數器就再+1。當其中某個對象不再引用A了,A的引用計數器會-1。直到A的引用計數減到了0,那么就沒有人再需要它了,就是時候把它釋放掉了
  • 版本二:對象通過 alloc copy new 生成得得對象在MRC年代需要手動管理內存, 利用得技術是returnCount引用計數器,來管理對象得釋放時機,alloc創建對象引用計數器 + 1, retain持有關系 引用計數器 +1,release 引用計數器 - 1。 如果當前對象得returnCount = 0 對象就會被在dealloc方法里面適當時機進行釋放(啥時候釋放?)如果當前returnCount大于0得時候,就會一直被持有。
  • 稍微詳細版本的,首先當 alloc copy new 生成得對象里面 在內部底層源碼也同時和當前對象相關聯得SideTable, 其內部有三個屬性, 一個是一把自旋鎖,一個是引用計數器相關,一個是維護weak生命得屬性得表, 其中retain、release 對利用鍵值對會對當前對象得引用計數器進行加減操作(位移),如果當前引用計數器為0得時候,其dealloc內部會刪除當前的引用計數器,并且釋放當前對象。
  • 詳情請查看http://www.lxweimin.com/p/ef6d9bf8fe59

雜項

  • 1、imageName與imageWithContentsOfFile區別?

  • imageWithContentsOfFile: 加載本地目錄圖片,并不會緩存,占用內存小, 不能加載image.xcassets里面的圖片資源。 相同的圖片會被重復加載到內存中

  • imageName:加載到內存中, 會緩存起來, 占用內存較大,相同的圖片不會被重復加載到內存當中,會讀取image.xcassets的圖片圖片資源。

  • 如果不斷重復讀取同一個圖片,則使用imageName

  • 如果不需要重復讀取同一個圖片,并且需要低內存,則使用imageWithContentsOfFile

  • 2.IBOutlet連出來的視圖屬性為什么可以被設置成weak?

  • 因為鏈接之Xcode 內部把鏈接的控件 放進了一個_topLevelObjectsToKeepAliveFromStoryboard的私有數組中,這個數組強引用這所有top level的對象 所以用weak也無傷大雅。

    1. id 為什么不能用點語法?
  • 點語法就是setter和getter方法, 然而id類 無法確定所指的類是什么類型, 尋不到setter個getter方法,id類型的對象 只能用【】方法調用方法

  • 4.id和NSObject的區別?

    • id是struct objc_object結構體指針,可以指向任何OC對象,當然不包括NSInteger等類型,因為這些數據類型不是OC對象。
  • 另外OC的基類不止有NSObject一個,還有個NSProxy虛類。所以說id類型和NSObject并不是等價的。

  • 5 . OC中 Null 與 nil的區別

    • NULL是指指針是空值,用來判斷C 指針;
    • nil是指一個OC對象(指針)為空;
    • Nil是指一個OC類為空;
    • NSNull則用于填充集合元素;這個類只有一個方法null,并且是單例的;
  • 6 . 自旋鎖和互斥鎖
  • 相同點:都能保證同一時間只有一個線程訪問共享資源,都能保證系統安全
  • 不同點:
互斥鎖:如果共享數據已經有了其他線程加鎖了,線程會進行休眠狀態等待鎖,一旦被訪問的資源被解鎖,則等待資源的線程會被喚醒。信號量dispatch_semaphore 為互斥鎖   @synchronized是NSLock的封裝 屬于互斥鎖  互斥鎖一般用于等待時間較長的情況
**適用于**:線程等待鎖的時間較長

自旋鎖:如果共享數據已經有其他線程加鎖了,線程會以死循環的方式等待鎖,一旦被訪問的資源被解鎖,則等待資源的線程會立即執行。OSSpinLock 屬于自旋鎖   自旋鎖一般用于時間較短的情況,OSSpinLock
**適用于**:線程等待鎖的時間較端
  • 7 . 進程和線程的區別

  • 進程是指在系統中正在運行的一個應用程序

  • 線程是進程中的一個實體,一個進程想要執行任務, 必須至少有一條線程,應程序啟動的時候會默認開啟一條線程,也就是主線程

  • 一個進程擁有多個線程

  • 8 LayoutSubviews和drawRect調用時機
    LayoutSubviews調用時機

    • init初始化不會調用LayoutSubviews方法
    • addsubView 時候會調用
    • 改變一個View的frame的時候調用
    • 滾動UIScrollView導致UIView重新布局的時候會調用
    • 手動調用setNeedsLayout或者layoutIfNeeded

drawRect調用時機

  • drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 兩方法之后掉用的.所以不用擔心在 控制器中,這些View的drawRect就開始畫了.、
  • 9 cocoaPods里面pod install和update的區別?
    **pod install **
  • 一般是第一次想要為項目添加pod的時候使用的,當然也可以在添加和移除庫使用
  • 每次pod install的時候,pod install 回為每一個安裝的pod庫在Podfile.lock文件中寫入其版本號,并且鎖定當前版本號。
  • 如果pod install的時候,不會更新其版本庫,而是去下載新的或者移除當前版本
    pod update
  • 當執行了pod update的時候,cocoaPods不會考慮Podfile.lock中的版本。直接去更新當前所有的庫到最新,然后Podfile.lock會更新這一次的版本號。
  • 10 frame和masonry哪個性能好?為什么
  • 有的相對布局最終都會轉換成Frame絕對布局 中間多了一層轉換的操作

  • 11 . iOS從iOS9 - 13的特性

iOS9

從HTTP升級到HTTPS
App瘦身 下面有講 這里不贅述( App瘦身 )
新增UIStackView

iOS10

新增通知推送相關的操作。自定義通知彈窗,自定義通知類型(地理位置,時間間隔,日歷等)

iOS11

無線 調試
齊劉海兒,導航條,安全距離等

iOS12

啟動速度優化
應用啟動速度提升40%
鍵盤響應速度提升50%
相機啟動速度提升70%

iOS13

黑暗模式 詳情請查閱 http://www.lxweimin.com/p/0da3b107f06c


二、App包以及啟動過程

App瘦身

1、App如何瘦身?

  • 刪除陳舊代碼、刪除陳舊xib/sb,刪除無用的圖片資源(檢測未使用圖片的工具LSUnusedResources
  • 無損壓縮圖片,本地音視頻壓縮。以直接減少圖片大小
  • 使用webP格式的圖片(加載速度比較慢,但可以達到瘦身的效果)
  • 減小類名稱的長度(高性能的話可以試一試)
  • 減少使用靜態庫
  • 一些主題類的東西提供下載功能,不直接打包在應用包里面,按需加載資源
  • iOS9 之后的新特性 應用程序切片(App Slicing)、中間代碼(Bitcode)和按需加載資源(On Demand Resources)

Slicing: 這個過程是iOS9出來之后 不需要程序員干預的一個瘦身的過程,簡單來說就是我們再上傳IPA包到iTunes Connect,然后AppStore會對app進行切片,切成特定的機型想要的數據,比如@3x給max用,@2x就自動剔除了。 是一個自動的過程
Bitcode:是一種中間碼,如果配置了Bitcode(Xcode7以后默認開啟)的程序會在App Store Connect上被重新編譯等一系列操作,進而蘋果內部會對可執行文件進行優化,也就是說不需要我們干預什么東西,也操作不了, 如果后面蘋果有更牛逼的優化操作,也是蘋果的事情, 跟我們個人開發者一毛錢關系沒有。
On Demand Resources 按需加載, 是程序員自己手動操作,說白了就是在用的時候去下載某些資源, 但是我們自己在配置的時候都需要配置,要額外寫一些代碼啥的,等我們提交到市場的時候, 蘋果內部會把我們按需加載的資源從包里面做了一些抽離操作啥的, 讓我們的包在下載的時候更小,舉個例子,就是吃雞里面沙漠地圖如果玩家不自己下載, 就玩不了沙漠。

on-demond resource(ODR)具體請查看原理版本:http://www.lxweimin.com/p/bacedd8a3ad8
或者詳細使用版本:http://www.cocoachina.com/articles/12155

關于 slicing, bitcode, on-demond resource(ODR)的參考資源https://blog.csdn.net/zhuod/article/details/70051514?utm_source=blogxgwz6


2、app啟動時候都經歷了什么?

啟動分為兩種。 一種是之前啟動過,按了一下home鍵,然后再點啟動,這個啟動叫熱啟動,另外就是第一次啟動app,或者啟動殺死之后的app 叫做冷啟動

根據info.plist里面的設置加載,建立沙箱,權限檢查等
加載可執行文件
加載動態庫
objc運行時的初始化處理(類的注冊,category注冊,selector唯一性檢查等等)
初始化,包括+load方法
執行main函數
Application 初始化,到 applicationDidFinishLaunchingWithOptions 執行完
渲染屏幕,到viewDidAppear 執行完畢,展現給用戶

  • mian之前

根據info.plist里面的設置加載,建立沙箱,權限檢查等
加載可執行文件
加載動態庫
objc運行時的初始化處理(類的注冊,category注冊,selector唯一性檢查等等)
初始化,包括+load方法

  • mian之后
    • 如圖
    • 加載流程如下:
      [圖片上傳失敗...(image-8500a-1597126379928)]

3、優化啟動時間

  • 啟動時間是用戶點擊App圖標,到第一個界面展示的時間。

注意:啟動時間在小于400ms是最佳的,因為從點擊圖標到顯示Launch Screen,到Launch Screen消失這段時間是400ms。啟動時間不可以大于20s,否則會被系統殺掉。

  • 以main函數作為分水嶺,啟動時間其實包括了兩部分:
    • main函數之前(分析并加載動態庫,注冊需要的類(包括系統的類),Category中的方法也會注冊到對用的類中,執行必要的初始化方法( +load方法)等等
    • main函數到第一個界面的viewDidAppear:
  • 所以,優化也是從兩個方面進行的,個人建議優先優化后者,因為絕大多數App的瓶頸在自己的代碼里。

mian函數之前的啟動優化

  • 減少動態庫的數量(這是目前為止最耗時的了, 基本上占了95%以上的時間)
  • 合并動態庫,比如自己寫的UI控件合并成自己的UIKit
  • 確認動態庫是optional還是required。如果該Framework在當前App支持的所有iOS系統版本都存在,那么就設為required,否則就設為optional,因為optional會有些額外的檢查
  • 合并Category(UIView+Frame,UIView+AutoLayout合并成一個)
  • 將不必需在+load方法中做的事情,延時放到+initialize。

mian函數之后的啟動優化
首先分析一下從main函數開始執行,到第一個頁面顯示, 這段時間做了哪些事情

  1. 執行didFinishLaunchingWithOptions方法
  2. 初始化Window,初始化基礎ViewContreoller(一般是UINavigationController+UITabViewController)
  3. 獲取數據(本地和遠程)
  4. 最后展示給用戶
  5. 減少創建線程(高性能iOS開發一書中提到,線程不僅僅有創建時的時間開銷,還會消耗內核的內存,即應用的內存空間。 每個線程大約消耗 1KB 的內核內存空間線程創建的耗時(不包含啟動時間),其區間范圍在 4000~5000 微秒,即 4~5 毫秒。創建線程后啟動線程的耗時區間為 5~100 毫秒,平均大約在 29 毫秒。這是很大的時間開銷,若在應用啟動時開啟多個線程,則尤為明顯。線程的啟動時間之所以如此之長,是因為多次的上下文切換所帶來的開銷。所以線程在開發過程中也避免濫用)
  6. 合并或者刪減不必要的類(或者分類)和函數objc的類越多,函數越多啟動越慢
  7. 在設計師可接受的范文盡量使用小的圖片
  • AppDelegate
    通常優化的一般來說,還是從AppDelegate先入手優化
didFinishLaunchingWithOptions
applicationDidBecomeActive

優化的核心思想就是,能延時的延時, 不能延時的盡量放到后臺去優化。

- 日志、統計等必須在 APP 一啟動就最先配置的事件。仍然把它留在 didFinishLaunchingWithOptions 里啟動。
- 項目配置、環境配置、用戶信息的初始化 、推送、IM等事件,這些功能在用戶進入 APP 主體的之前是必須要加載完的,把他放到廣告頁面的viewDidAppear啟動。
- 其他 SDK 和配置事件,由于啟動時間不是必須的,所以我們可以放在第一個界面的 viewDidAppear 方法里,這里完全不會影響到啟動時間。
- 每次用NSLog方式打印會隱式的創建一個Calendar,因此需要刪減啟動時各業務方打的log,或者僅僅針對內測版輸出log
- 盡量不要在didFinishLaunchingWithOptions 里面創建和開啟多線程

參考文獻http://www.lxweimin.com/p/f40fdd8799b8
其文章內部作者談到了美團關于啟動優化的相關分析,看似似曾相似,沒記錯的畫《高性能iOS應用開發》這本書就是美團這幾個哥們兒翻譯的吧,實現方式和書中頗為相似。


3、App電量消耗

  • 1.定位
  • 2.網絡請求
  • 3.CPU處理
  • 4.GPU處理
  • 5.Bluetooth

定位優化

1.盡量不要實時更新
2.定位精度盡量不要太高

網絡優化

1.減少、壓縮網絡數據
2.能使用緩存就使用緩存,減少網絡請求
3.斷點續傳
4.批量傳輸
5.設置適合的超時時間,用戶可以取消耗時的網絡請求
6.網絡不可用時就不要再執行網絡請求了

CPU/GPU優化

相關離屏渲染操作盡量避免
內存管理處理好
使用懶加載
使用繪制
圖片與imageView相同大小避免多余運算
Timer的時間間隔不宜太短,滿足需求即可
線程適量,不宜過多,不要阻塞主線程
適當使用多線程
減少視圖刷新:確保必要的時候才刷新,能刷新1行cell最好只刷新一行;

為了優化耗電我們還可以做:
1.盡量不要使用定時器
2.優化I/O操作(文件的讀寫操作)
2.1最好不要頻繁讀寫小數據,最好批量讀寫
2.2數據量比較大的時候可以考慮使用數據庫
2.3讀寫大量重要數據時,考慮用dispatch_io,其提供了基于GCD的異步操作文件I/O的API。用dispatch_io系統會優化磁盤訪問

高性能iOS應用開發中提到一下幾點

  • 1、CPU優化
  • 數據處理(例如文本格式優化)
  • 待處理的數據大小----更大的顯示屏允許軟件在單個視圖中展示更多的信息,但這也意味著要處理更多的數據
  • 處理數據的算法和數據結構
  • 執行更新的次數,尤其是在數據更新之后,觸發應用的狀態或者UI進行更新(比如刷新單行cell)
  • 服務器中的數據盡量不要在客戶端上處理(例如服務器字符串,在客戶端進行拆分操作)
  • 按需加載(例如tableViewcell 不需要一下子全部渲染,快速滑動的時候 過程中的留白處理。)
  • 2、網絡
  • 在進行網絡請求之前,先檢查是否有網絡連接。(沒網絡的時候,不要請求網絡)
  • 避免沒有連接WiFi的情況下進行高帶寬的消耗操作(因為3G、4G等手機網絡耗電量遠大于WIFi信號),例如視頻流在4G或者非Wifi情況下應該給出響應的提示。
  • 3、定位
  • 盡量不要實時更新
  • 定位精度盡量不要太高
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,690評論 2 370