1. 程式人生 > >IOS組織架構圖

IOS組織架構圖

Cocoa框架是iOS應用程式的基礎,瞭解Cocoa框架,對開發iOS應用有很大的幫助。

1、Cocoa是什麼?

Cocoa是OS X和 iOS作業系統的程式的執行環境。

是什麼因素使一個程式成為Cocoa程式呢?不是程式語言,因為在Cocoa開發中你可以使用各種語言;也不是開發工具,你可以在命令列上就可以建立Cocoa程式。Cocoa程式可以這麼說,它是由一些物件組成,而這些物件的類最後都是繼承於它們的根類 :NSObject。而且它們都是基於Objective-C執行環境的。

1.1、Cocoa框架

iOS中,Cocoa眾多框架中最重要最基本的兩個框架是:Foundation 和 UIKit。

Foundation 和介面無關,也可以說和介面無關的類基本是Foundation框架的,和介面相關的是UIKit框架。

這兩個框架在系統中處於的位置如圖:

1.2、Foundation框架

好吧,那我們看看兩個框架的類組織架構圖,第一個先看Foundation的,三個圖,包括了Foundation所以的類,圖中灰色的是iOS不支援的,灰色部分是OS X系統的。

  


將上圖Foundation框架中的類進行邏輯分類如下:

  1. 值物件
  2. 集合 
  3. 作業系統服務 包括下面三個:檔案系統和URL   程序間通訊。 這個範疇中的大部分類代表不同的系統埠、套接字、和名字伺服器,對實現底層的IPC很有用。NSPipe代表一個BSD管道,即一種程序間的單向通訊通道。   執行緒和子任務。
     NSThread類使您可以建立多執行緒的程式,而各種鎖(lock)類則為彼此競爭的執行緒在訪問程序資源時提供各種控制機制。通過NSTask,您的程式可以分出      一個子程序來執行其它工作或進行進度監控。
  4. 通知
  5. 歸檔和序列化
  6. 表示式和條件判斷
  7. Objective-C語言服務

1.3 UIKit框架

應用程式可以通過三種方式使用UIKit建立介面
  1.   在使用者介面工具(interface Buidler)從物件庫裡 拖拽視窗,檢視或者其他的物件使用。
  2.   用程式碼建立
  3.   通過繼承UIView類或間接繼承UIView類實現自定義使用者介面
框架類組織架構圖:

在圖中可以看出,responder 類是圖中最大分支的根類,UIResponder為處理響應事件和響應鏈 定義了介面和預設行為。當用戶用手指滾動列表或者在虛擬鍵盤上輸入時,UIKit就生成時間傳送給UIResponder響應鏈,直到鏈中有物件處理這個事件。相應的核心物件,比如:UIApplication  ,UIWindow,UIView都直接或間接的從UIResponder繼承。

 2、Cocoa物件

2.1 Objective-C是面向物件的語言

Objective-C和Java C++一樣,有封裝,繼承,多型,重用。但是它不像C++那樣有過載操作法、模版和多繼承,也沒有Java的垃圾回收機制。

2.2 Objective-C的優點

Objective-C語言有C++ Java等面向物件的特點,那是遠遠不能體現它的優點的。Objective-C的優點是它是動態的。動態能力有三種:

動態類-執行時確定類的物件

動態繫結-執行時確定要呼叫的方法

動態載入--執行時為程式載入新的模組

2.3 動態能力相關的isa指標

每個Objective-C物件都有一個隱藏的資料結構,這個資料結構是Objective-C物件的第一個成員變數,它就是isa指標。這個指標指向哪呢?它指向一個類物件(class object  記住它是個物件,是佔用記憶體空間的一個變數,這個物件在編譯的時候編譯器就生成了,專門來描述某個類的定義),這個類物件包含了Objective-C物件的一些資訊(為了區分兩個物件,我把前面提到的物件叫Objective-C物件),包括Objective-C物件的方法排程表,實現了什麼協議等等。這個包含資訊就是Objective-C動態能力的根源了。

那我們看看isa指標型別的資料結構是什麼樣的?如果拋開NSObject物件的其他的成員資料和變數,NSObject可以看成這樣:

  1. @interface NSObject <NSObject> {  
  2.      Class    isa;  
  3. }   
不考慮@interface關鍵字在編譯時的作用,可以把NSObject更接近C語言結構表示為:
  1. struct NSObject{  
  2.    Class isa;  
  3.  }  
Class是用typedef 定義的
  1. typedefstruct objc_class *Class;  
那NSObject可以這麼寫了
  1. struct NSObject{  
  2.   objc_class *isa  
  3. }  
那objc_class的結構是什麼樣的呢?大概是這樣的:
  1. struct objc_class {  
  2.      Class isa;  
  3.      Class super_class;  
  4.      constchar *name;  
  5.      long version;  
  6.      long info;  
  7.      long instance_size;  
  8.      struct objc_ivar_list *ivars;  
  9.      struct objc_method_list **methodLists;   
  10.      struct objc_cache *cache;  
  11.      struct objc_protocol_list *protocols;     
  12.  }  
這裡會看到,在這個結構體裡還有一個isa指標,又是一重指向,是不是有種到了盜夢空間的感覺。不用緊張,take easy,不會有那麼多層次的,這裡的isa指標指向的是元類物件(metaclass object),帶有元字,證明快到頭了。那元物件有啥用呢?它用來儲存的關於類的版本,名字,類方法等資訊。所有的元類物件(metaclass object)都指向 NSObject的元類物件,到頭還是NSObject。一共三次:類物件->元類物件->NSObject元類物件。

   為了得到整個類組織架構的資訊,objc_class結構裡定義了第二個成員變數Class super_class,它指向父類的類物件。說了這麼多,可能關係縷不清楚,有道是一張圖勝過千言萬語


圖中可以看出,D3繼承D2,D2繼承D1,D1最終繼承NSObject。下圖從D3的一個物件開始,排列出D3 D2 D1 NSObject 類物件,元類物件等關係。


圖中的箭頭都是指標的指向。

2.4 根類 NSObject

NSObject是大部分Objective-C類的根類,它沒有父類。其它類繼承NSObject,訪問Objective-C執行時系統的基本介面,這樣其他類的例項可以獲得執行時的能力。


2.4.1 根類和根類協議

NSObject不但是個類名,NSObject也是個協議的名稱,參考NSObject協議 , NSObject協議指定了根類必須實現的介面。

2.4.2 根類的主要方法:

  •     分配、初始化、和複製:
alloc和allocWithZone:方法用於從某記憶體區域中分配一個物件記憶體,並使物件指向其執行時的類定義。
init方法是物件初始化。
new是一個將簡單的記憶體分配和初始化結合起來的方法。
copy和copyWithZone:
  • 物件的保持和清理:
retain方法增加物件的保持次數。
release方法減少物件的保持次數。
autorelease方法也是減少物件的保持次數,但是以推遲的方式。
retainCount方法返回對當前的保持次數。
dealloc方法由需要釋放物件的例項變數以及釋放動態分配的記憶體的類實現。
  • 內省和比較

NSObjec有很多方法可以查詢物件的執行時資訊。這些內省方法有助於找出物件在類層次中的位置,確定物件是否實現特定的方法,以及測試物件是否遵循某種協議。下面是部分方法 
superclass和class方法(實現為類和例項方法)分別以Class物件的形式返回接收者的父類和類。
您可以通過isKindOfClass:和isMemberOfClass:方法來確定物件屬於哪個類。後者用於測試接收者是否為指定類的例項。isSubclassOfClass:類方法則用於測試類的繼承性。
respondsToSelector:方法用於測試接收者是否實現由選擇器引數標識的方法。instancesRespondToSelector:類方法則用於測試給定類的例項是否實現指定的方法。
conformsToProtocol:方法用於測試接收者(物件或類)是否遵循給定的協議。
isEqual:和hash方法用於物件的比較。
description方法允許物件返回一個內容描述字串;這個方法的輸出經常用於除錯(“print object”命令),以及在格式化字串中和“%@”指示符一起表示物件。

  • 物件的編碼和解碼

下面的方法和物件的編解碼(作為歸檔過程的一部分)有關:
encodeWithCoder:和initWithCoder:是NSCoding協議僅有的方法。前者使物件可以對其例項變數進行編碼,後者則使物件可以根據解碼過的例項變數對自身進行初始化。
NSObject類中聲明瞭一些於物件編碼有關的方法:classForCoder:、replacementObjectForCoder:、和awakeAfterUsingCoder:。

  • 訊息的轉發

forwardInvocation:允許一個物件將訊息轉發給另一個物件。

  • 訊息的派發 

在performSelector開頭的一些方法允許你延遲後派髮指定訊息,而且可以將訊息(同步或非同步的訊息)從輔助執行緒派發到主執行緒。

2.5 Cocoa物件生命週期

物件的四種記憶體管理方式,如下圖所示

  •  物件的生命週期—簡化檢視


  • 保持接收到的物件


  • 拷貝接收到的物件


  • 自動釋放池


參考:

1、http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf

2、http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/Introduction.html

3、http://www.cnblogs.com/csutanyu/archive/2011/12/12/Objective-C_memory_layout.html