iOS 開發中的一些簡單總結

ObjC

屬性

  • @property 的本質是生成setter方法和getter方法以及一個帶下劃線的成員變量,經過autosynthesis添加到類中的。ios

  • 一般的關鍵字爲:objective-c

    • nonatomic & atomicsegmentfault

      這是表明原子性 可是atomic不能徹底保證線程安全 它只保證了setter和getter方法的線程安全,具體的狀況:當A線程進行寫操做的時候,B線程會等待。當A線程寫完,B線程進行寫操做,而後A線程讀取的將是B線程中的值,若是C線程在A線程讀寫前將對象release了還會形成程序崩潰api

    • strong & retain數組

      strong至關於ARC下的retain 會強引用對象 使得對象的引用計數加一緩存

    • weak & assign安全

      assign多被用來修飾基本數據類型,是指針賦值,不會對引用計數操做,使用以後不會自動置nil,可能會致使野指針。A對象的指針賦值給B,此時B只是保存了A的指針,不會持有A,因此當A被釋放的時候再訪問B可能會出現野指針錯誤。bash

      weak表示弱引用,它既不會設置新值,也不會保存舊值。不會對引用計數操做,當指向的對象被釋放以後,自身也會被置nil多線程

    • copy異步

      copy是對對象的引用計數加一,它對應的setter方法不會保存新值,而是將其拷貝一份,一般NSString以及具備可變類型的集合類型可使用copy修飾,拷貝一份出來,以保證不會再使用的過程當中被其餘地方的操做所改變

      block也使用copy來修飾,這是MRC遺留下的傳統,提示開發者block是從棧上覆制到堆上的。

    • readwrite&readonly

      讀寫,只讀

    • setter= & getter=

      指定setter方法和getter方法

    • 默認

      基本數據類型默認是assign, atomic,readwirte

      對象類型strong,atomic, readwrite

@synthesize 自動生成setter getter方法

@dynamic不須要編譯器生成,手動生成

默認是@synthesize var = _var

對象copy

  • 拷貝的本質是生成一份獨立的副本

  • 對不可變對象來講 copy是淺拷貝,由於該對象自己就是不可變的了。而mutablecopy是深拷貝由於須要拷貝出來一份可變的對象,因此須要進行深拷貝,拷貝內存中的內容。

  • 對可變對象來講,copy和mutable拷貝都是深拷貝,copy生成的對象是不可變的,mutablecopy會生成可變對象

copy & mutableCopy

  • 自定義對象想要進行copy操做須要實現NSCopying協議

    • 實現copyWithZone或者mutableCopyWithZone方法

      - (id)copyWithZone:(NSZone *)zone {
          Person *p = [[Person allocWithZone:zone] init];
          //屬性也要拷貝賦值
          p.name = [self.name mutableCopy];
          p.age = self.age;
          return p;
      }
      複製代碼
    • 若是Person中有其餘自定義對象,那麼該自定義對象也須要實現遵循並實現 NSCopying協議。

類和對象

  • NSObject 實例本質是一個結構體
  • NSObect對象的大小是一個C語言結構體的大小
  • 實例對象的isa指針指向類對象,類對象的isa指向元類對象。
  • 每一個類中只有一個類對象,類對象中存放了對象的方法列表,協議列表等本質是一個object_class結構體
  • 每個類中只有一個元類對象,元類對象的結構跟類對象是同樣只不過用途不同。能夠經過 runtime 的 class_isMetaClass 來驗證某個類是否是元類,其本質是一個 objc_class 的結構體。
  • 有繼承關係的對象的結構體中存放着其父類的結構體

+ initialize 與 +load

  • 調用時機
    • + initialize第一次初始化這個類以前調用,咱們經常使用來初始化靜態變量,是runtime負責的。
    • +load 方法會在加載類的時候就被調用,也就是 ios 應用啓動的時候,就會加載全部的類,就會調用每一個類的 + load 方法。load經過指針直接找到函數地址直接調用沒有經過消息機制
  • 大量使用load會致使App啓動速度變慢

Category

可使用Category爲類添加新方法,使用Category爲類添加新方法在必定程度上比使用繼承添加方法的釋放耦合度低。

category是不支持直接使用屬性的,能夠經過runtime的屬性綁定來實現。聲明一個屬性,實現setter和getter方法。在setter方法中使用objc_setAssociatedObject第二個參數標記能夠用``@selector([getter method name]),getter方法中使用objc_getAssociatedObject獲取屬性值,第二個參數使用_cmd`

category 中實現的方法是在運行時添加到類中的。category是按照編譯順序排列的,因此後編譯的cat中取出的方法、屬性和協議列表,分別放在mlist、proplists和protolists的最前面。

Block

block的本質是封裝了函數調用和函數調用環境的OC對象

  1. Block對變量的捕獲:

    • auto變量 值捕獲
    • static 引用捕獲
    • 全局變量不會捕獲
  2. block類型

    MRC下 當block訪問了auto類型變量的時候是stackblock 其餘狀況下是globalblock

    ARC下會將stackblock從棧上copy到堆上,固然這是編譯器幫咱們作的

  3. ARC下的block會在一下狀況自動調用copy方法

    • block做爲返回值的時候
    • 當block被強指針引用的時候
    • cocoa api中 做爲usingBlock 或者GCD的參數的時候
  4. 對象類型的捕獲

    • 會根據對象的修飾詞對變量進行retain或者弱引用,當block從堆中移除的時候對應的dispose方法釋放對象
  5. __weak

    ARC下一般使用__weak來解決block的循環引用問題,使用它修飾的對象在被block捕獲的時候,在block內部也會使用__weak來修飾,而使用__weak修飾的對象會被弱引用。

  6. __block

    在block內部修改auto變量的時候一般會報錯,這個時候須要使用__block修飾。__block修飾的變量,在block內部會生成一個結構體,結構體中存放有isa指針__forwarding指針,變量等信息,當改變變量的值得時候會經過__forwarding指針找到這個結構體,改變其中變量的值。

KVO KVC

  1. KVO是鍵值監聽,當對一個對象進行KVO的時候,runtime會建立一個新的對象做爲以前對象的子類,這個子類中重寫了變量的setter方法,class方法和dealloc方法,調用Foundation中的_NSSetIntValueAndNotify函數,它會在賦值以前調用willChangeValueForKey,以後調用didChangeValueForKey來監聽值得改變。
  2. KVC是鍵值編碼
    • 設置值的時候會按照setKey,_setKey的順序查找setter方法,若是找到則直接調用設置值,找不到則查看+ (BOOL)accessInstanceVariablesDirectly方法的返回值,若是返回值是NO則調用setValue:forUndefinedKey方法,若是沒有實現會拋出異常。若是是YES,則會按照_key,_isKey,key,isKey的順序查找成員變量賦值
    • 獲取值的時候會按照getKeykeyisKey_key的順序查找對應的方法,若是找到則展開調用,若是找不到那麼查看+ (BOOL)accessInstanceVariablesDirectly返回值,YES的話會按照_key,_isKey,key,isKey的順序查找成員變量,返回NO的話就會調用- (id)valueForUndefinedKey:(NSString *)key,若是沒有實現會拋出異常
    • + (BOOL)accessInstanceVariablesDirectly默認爲YES

內存

iOS 使用引用計數的方式管理內存,內存管理的原則是誰建立,誰釋放 。 誰引用,誰管理

使用new、alloc、copy或者mutable copy,引用計數爲初始值1,再使用retain的話,引用計數爲+1,使用release或者autorelease會使引用計數-1。

自動釋放池,OC對象調用autorelase方法以後,會將對象放到離本身最近的自動釋放池內,Run Loop在每一個事件循環結束後會去自動釋放池,會將釋放池內全部的對象都作一次release操做。

MRC下的setter方法

先釋放舊值再引用新值

- (void)setAge:(NSString *)age {
		if (_age != age) {
      	[_age release];
      	[age retain];
        _age = age;
		}
}
複製代碼

循環引用

  • Block
  • NSTimer
  • self 加到array中
  • delegate

多線程

iOS的多線程方案:

  1. GCD :GCD中有四種隊列:主隊列、串行隊列、並行隊列、全局隊列。全局隊列是一種特殊的並行隊列,它沒有標識。同步只能在當前線程中執行,不會開闢新線程,且都是串行執行任務。異步線程在主隊列中不會建立線程,在並行隊列中會開啓新線程並行執行任務,串行隊列會建立線程串行執行任務。
  2. 線程間通訊可使用performSelector:onThread...
  3. 隊列組
  4. NSOperation 是GCD的OC封裝,它是一個抽象類,不能直接使用,須要使用其子類。NSOperation能夠提供 OC Api操做線程,還能夠指定依賴關係,而且可使用KVO監放任務的執行狀況
  5. 信號量
    • OSSpinLock 自旋鎖,會處於忙等的狀態
      • OSSpinLock & OSSpinUnLock
    • os_unfair_lock 用來代替OSSpinLock 屬於互斥鎖會進入休眠狀態
      • os_unfair_lock_lock & os_unfair_lock_unlock
    • pthread_mutex 屬於pthread的api
      • 遞歸鎖 & 條件鎖
    • NSLock 對 pthread_mutex的封裝
    • @synchronized 對mutex遞歸鎖的封裝
    • dispatch_barrier_async 要求線程必須是dispatch_queue_cretate建立的,讀寫操做的時候可使用柵欄函數隔離寫操做。

runtime

  • 更換系統字體
  • 爲category添加屬性
  • 字典轉模型
  • NSCoding協議

objcMsgSend

首先會在方法緩存中查找方法的實現,若是沒有找到則查找父類的實現,父類沒有實現會進入動態方法解析,爲該類添加一個方法的實現。若是動態方法解析尚未實現,那麼會進入消息轉發,將消息轉發給一個能夠相應該方法的target。若是這一步尚未實現則會進行方法簽名,返回一個方法簽名,並調用forwardInvacation返回一個target處理該消息,若是尚未實現則會報方法找不到錯誤。

runloop

  1. 首先會通知監聽者Observers:即將處理Timers

  2. 通知監聽者Observers:即將處理Sources

  3. 處理blocks

  4. 處理source0,若是處理完了會再次處理blocks

  5. 若是存在source1,則跳到handle_msg處理,若是沒有則通知監聽器即將進入休眠

  6. 休眠時期等待消息來喚醒當前線程

  7. 若是有消息喚醒則進入handle_msg處理計時器,gcd,source1這些信息

  8. 再次處理blocks

  9. 獲取返回值retVal

  10. 進入do-while(),若是retVal == 0 則循環持續進行。不然返回給CFRunLoopRunSpecific函數,退出RunLoop

UI

UITableView

  1. 優化
    1. 儘可能不要使用透明的顏色
    2. 不要動態的添加控件
    3. 注意重用id
    4. 在model中緩存高度
    5. 儘可能一次將控件添加到cell上使用hidden來控制顯隱
    6. 圓角處理避免離屏渲染
  2. 重用機制
    1. 首先會按照屏幕顯示建立cell,存放在visiableCells數組中
    2. 滑動出屏幕的cell會放到reuseableCells的數組中,從visiableCells中移除
    3. 重用的時候回檢查reuseableCells中是否有相同id的cell
  3. reload
    1. reloadData:猜想是將visiableCells中全部cell移入reusableTableCellsvisiableCells清空。cellForRowAtIndexPath調用後,再把reuse的cell從reusableTableCells取出來,放入到visiableCells
    2. reloadRowsAtIndex: 若是調用時reusableTableCells爲空,那麼cellForRowAtIndexPath調用後,是新建立cell,新的cell加入到visiableCells。老的cell移出visiableCells,加入到reusableTableCells

響應者鏈

iOS響應者鏈完全掌握

其餘

HTTP&HTTPS

  1. client向server發送請求https://baidu.com,而後鏈接到server的443端口。

  2. 服務端必需要有一套數字證書,能夠本身製做,也能夠向組織申請。區別就是本身頒發的證書須要客戶端驗證經過,才能夠繼續訪問,而使用受信任的公司申請的證書則不會彈出提示頁面,這套證書其實就是一對公鑰和私鑰。

  3. 傳送證書 這個證書其實就是公鑰,只是包含了不少信息,如證書的頒發機構,過時時間、服務端的公鑰,第三方證書認證機構(CA)的簽名,服務端的域名信息等內容。

  4. 客戶端解析證書 這部分工做是由客戶端的TLS來完成的,首先會驗證公鑰是否有效,好比頒發機構,過時時間等等,若是發現異常,則會彈出一個警告框,提示證書存在問題。若是證書沒有問題,那麼就生成一個隨即值(祕鑰)。而後用證書對該隨機值進行加密。

  5. 傳送加密信息 這部分傳送的是用證書加密後的祕鑰,目的就是讓服務端獲得這個祕鑰,之後客戶端和服務端的通訊就能夠經過這個隨機值來進行加密解密了。

  6. 服務段加密信息 服務端用私鑰解密祕密祕鑰,獲得了客戶端傳過來的私鑰,而後把內容經過該值進行對稱加密。

  7. 傳輸加密後的信息 這部分信息是服務端用私鑰加密後的信息,能夠在客戶端被還原。

  8. 客戶端解密信息

    客戶端用以前生成的私鑰解密服務端傳過來的信息,因而獲取瞭解密後的內容。

上述文字出自HTTP和HTTPS協議,看一篇就夠了

源碼

相關文章
相關標籤/搜索