轉載自:http://blog.csdn.net/totogo2010/article/details/8081253
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架構中的類進行邏輯分類如下:
- 值對象
- 集合
- 作業系統服務 包括下面三個:檔案系統和URL 程序間通訊。 這個範疇中的大部分類代表不同的系統端口、套接字、和名字伺服器,對實作底層的IPC很有用。NSPipe代表一個BSD管道,即一種程序間的單向通訊通道。 線程和子任務。 NSThread類使您可以建立多線程的程式,而各種鎖(lock)類則為彼此競争的線程在通路程序資源時提供各種控制機制。通過NSTask,您的程式可以分出 一個子程序來執行其它工作或進行進度監控。
- 通知
- 歸檔和序列化
- 表達式和條件判斷
- Objective-C語言服務
1.3 UIKit架構
應用程式可以通過三種方式使用UIKit建立界面
- 在使用者界面工具(interface Buidler)從對象庫裡 拖拽視窗,視圖或者其他的對象使用。
- 用代碼建立
- 通過繼承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可以看成這樣:
[cpp] view plain copy
- @interface NSObject <NSObject> {
- Class isa;
- }
不考慮@interface關鍵字在編譯時的作用,可以把NSObject更接近C語言結構表示為:
[cpp] view plain copy
- struct NSObject{
- Class isa;
- }
Class是用typedef 定義的
[cpp] view plain copy
- typedef struct objc_class *Class;
那NSObject可以這麼寫了
[cpp] view plain copy
- struct NSObject{
- objc_class *isa
- }
那objc_class的結構是什麼樣的呢?大概是這樣的:
[cpp] view plain copy
- struct objc_class {
- Class isa;
- Class super_class;
- const char *name;
- long version;
- long info;
- long instance_size;
- struct objc_ivar_list *ivars;
- struct objc_method_list **methodLists;
- struct objc_cache *cache;
- struct objc_protocol_list *protocols;
- }
這裡會看到,在這個結構體裡還有一個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
容芳志 (http://blog.csdn.net/totogo2010)
本文遵循“署名-非商業用途-保持一緻”創作公用協定