Cocoa框架是iOS應(yīng)用程序的基礎(chǔ),了解Cocoa框架,對(duì)開發(fā)iOS應(yīng)用有很大的幫助访雪。
Cocoa是OS X和 iOS操作系統(tǒng)的程序的運(yùn)行環(huán)境臣缀。
是什么因素使一個(gè)程序成為Cocoa程序呢坝橡?不是編程語言,因?yàn)樵贑ocoa開發(fā)中你可以使用各種語言精置;也不是開發(fā)工具计寇,你可以在命令行上就可以創(chuàng)建
Cocoa程序。Cocoa程序可以這么說脂倦,它是由一些對(duì)象組成番宁,而這些對(duì)象的類最后都是繼承于它們的根類
:NSObject。而且它們都是基于Objective-C運(yùn)行環(huán)境的赖阻。
iOS中,Cocoa眾多框架中最重要最基本的兩個(gè)框架是:Foundation 和 UIKit火欧。
Foundation 和界面無關(guān)棋电,也可以說和界面無關(guān)的類基本是Foundation框架的,和界面相關(guān)的是UIKit框架苇侵。
這兩個(gè)框架在系統(tǒng)中處于的位置如圖:
好吧,那我們看看兩個(gè)框架的類組織架構(gòu)圖衅檀,第一個(gè)先看Foundation的招刨,三個(gè)圖,包括了Foundation所以的類哀军,圖中灰色的是iOS不支持的沉眶,灰色部分是OS X系統(tǒng)的。
將上圖Foundation框架中的類進(jìn)行邏輯分類如下:
值對(duì)象
集合
操作系統(tǒng)服務(wù) 包括下面三個(gè):文件系統(tǒng)和URL進(jìn)程間通訊杉适。這個(gè)范疇中的大部分類代表不同的系統(tǒng)端口谎倔、套接字、和名字服務(wù)器猿推,對(duì)實(shí)現(xiàn)底層的IPC很有用片习。NSPipe代表一個(gè)BSD管道,即一種進(jìn)程間的單向通訊通道蹬叭。線程和子任務(wù)藕咏。NSThread類使您可以創(chuàng)建多線程的程序,而各種鎖(lock)類則為彼此競(jìng)爭(zhēng)的線程在訪問進(jìn)程資源時(shí)提供各種控制機(jī)制秽五。通過NSTask孽查,您的程序可以分出 ? ? ?一個(gè)子進(jìn)程來執(zhí)行其它工作或進(jìn)行進(jìn)度監(jiān)控。
通知
歸檔和序列化
表達(dá)式和條件判斷
Objective-C語言服務(wù)
應(yīng)用程序可以通過三種方式使用UIKit創(chuàng)建界面
在用戶界面工具(interface Buidler)從對(duì)象庫里 拖拽窗口坦喘,視圖或者其他的對(duì)象使用盲再。
用代碼創(chuàng)建
通過繼承UIView類或間接繼承UIView類實(shí)現(xiàn)自定義用戶界面
框架類組織架構(gòu)圖:
在圖中可以看出西设,responder 類是圖中最大分支的根類,UIResponder為處理響應(yīng)事件和響應(yīng)鏈
定義了界面和默認(rèn)行為答朋。當(dāng)用戶用手指滾動(dòng)列表或者在虛擬鍵盤上輸入時(shí)贷揽,UIKit就生成時(shí)間傳送給UIResponder響應(yīng)鏈,直到鏈中有對(duì)象處理這個(gè)
事件梦碗。相應(yīng)的核心對(duì)象禽绪,比如:UIApplication ?,UIWindow叉弦,UIView都直接或間接的從UIResponder繼承丐一。
Objective-C和Java C++一樣淹冰,有封裝,繼承巨柒,多態(tài)樱拴,重用。但是它不像C++那樣有重載操作法洋满、模版和多繼承晶乔,也沒有Java的垃圾回收機(jī)制。
Objective-C語言有C++ Java等面向?qū)ο蟮奶攸c(diǎn)牺勾,那是遠(yuǎn)遠(yuǎn)不能體現(xiàn)它的優(yōu)點(diǎn)的正罢。Objective-C的優(yōu)點(diǎn)是它是動(dòng)態(tài)的。動(dòng)態(tài)能力有三種:
動(dòng)態(tài)類-運(yùn)行時(shí)確定類的對(duì)象
動(dòng)態(tài)綁定-運(yùn)行時(shí)確定要調(diào)用的方法
動(dòng)態(tài)加載--運(yùn)行時(shí)為程序加載新的模塊
2.3 動(dòng)態(tài)能力相關(guān)的isa指針
每個(gè)Objective-C對(duì)象都有一個(gè)隱藏的數(shù)據(jù)結(jié)構(gòu)驻民,這個(gè)數(shù)據(jù)結(jié)構(gòu)是Objective-C對(duì)象的第一個(gè)成員變量翻具,它就是isa指針。這個(gè)指針指向哪
呢回还?它指向一個(gè)類對(duì)象(class object
記住它是個(gè)對(duì)象裆泳,是占用內(nèi)存空間的一個(gè)變量,這個(gè)對(duì)象在編譯的時(shí)候編譯器就生成了柠硕,專門來描述某個(gè)類的定義)工禾,這個(gè)類對(duì)象包含了Objective-C
對(duì)象的一些信息(為了區(qū)分兩個(gè)對(duì)象,我把前面提到的對(duì)象叫Objective-C對(duì)象)蝗柔,包括Objective-C對(duì)象的方法調(diào)度表闻葵,實(shí)現(xiàn)了什么協(xié)議等
等。這個(gè)包含信息就是Objective-C動(dòng)態(tài)能力的根源了癣丧。
那我們看看isa指針類型的數(shù)據(jù)結(jié)構(gòu)是什么樣的槽畔?如果拋開NSObject對(duì)象的其他的成員數(shù)據(jù)和變量,NSObject可以看成這樣:
@interface?NSObject??{
Class????isa;
}
不考慮@interface關(guān)鍵字在編譯時(shí)的作用坎缭,可以把NSObject更接近C語言結(jié)構(gòu)表示為:
structNSObject{
Class?isa;
}
Class是用typedef 定義的
typedefstructobjc_class?*Class;
那NSObject可以這么寫了
structNSObject{
objc_class?*isa
}
那objc_class的結(jié)構(gòu)是什么樣的呢竟痰?大概是這樣的:
structobjc_class?{
Class?isa;
Class?super_class;
constchar*name;
longversion;
longinfo;
longinstance_size;
structobjc_ivar_list?*ivars;
structobjc_method_list?**methodLists;
structobjc_cache?*cache;
structobjc_protocol_list?*protocols;
}
這里會(huì)看到签钩,
在這個(gè)結(jié)構(gòu)體里還有一個(gè)isa指針,又是一重指向,是不是有種到了盜夢(mèng)空間的感覺。不用緊張蛋欣,take
easy淹真,不會(huì)有那么多層次的,這里的isa指針指向的是元類對(duì)象(metaclass
object)挨决,帶有元字,證明快到頭了。那元對(duì)象有啥用呢兔沃?它用來存儲(chǔ)的關(guān)于類的版本,名字级及,類方法等信息乒疏。所有的元類對(duì)象(metaclass
object)都指向
NSObject的元類對(duì)象,到頭還是NSObject饮焦。一共三次:類對(duì)象->元類對(duì)象->NSObject元類對(duì)象怕吴。
為了得到整個(gè)類組織架構(gòu)的信息,objc_class結(jié)構(gòu)里定義了第二個(gè)成員變量Class super_class县踢,它指向父類的類對(duì)象转绷。說了這么多,可能關(guān)系縷不清楚硼啤,有道是一張圖勝過千言萬語
圖中可以看出议经,D3繼承D2,D2繼承D1,D1最終繼承NSObject。下圖從D3的一個(gè)對(duì)象開始谴返,排列出D3 D2 D1 NSObject 類對(duì)象煞肾,元類對(duì)象等關(guān)系。
圖中的箭頭都是指針的指向亏镰。
NSObject是大部分Objective-C類的根類扯旷,它沒有父類。其它類繼承NSObject索抓,訪問Objective-C運(yùn)行時(shí)系統(tǒng)的基本接口钧忽,這樣其他類的實(shí)例可以獲得運(yùn)行時(shí)的能力。
NSObject不但是個(gè)類名逼肯,NSObject也是個(gè)協(xié)議的名稱耸黑,參考NSObject協(xié)議, NSObject協(xié)議指定了根類必須實(shí)現(xiàn)的接口篮幢。
分配大刊、初始化、和復(fù)制:
alloc和allocWithZone:方法用于從某內(nèi)存區(qū)域中分配一個(gè)對(duì)象內(nèi)存三椿,并使對(duì)象指向其運(yùn)行時(shí)的類定義缺菌。
init方法是對(duì)象初始化葫辐。
new是一個(gè)將簡(jiǎn)單的內(nèi)存分配和初始化結(jié)合起來的方法。
copy和copyWithZone:
對(duì)象的保持和清理:
retain方法增加對(duì)象的保持次數(shù)伴郁。
release方法減少對(duì)象的保持次數(shù)耿战。
autorelease方法也是減少對(duì)象的保持次數(shù),但是以推遲的方式焊傅。
retainCount方法返回對(duì)當(dāng)前的保持次數(shù)剂陡。
dealloc方法由需要釋放對(duì)象的實(shí)例變量以及釋放動(dòng)態(tài)分配的內(nèi)存的類實(shí)現(xiàn)。
內(nèi)省和比較
NSObjec有很多方法可以查詢對(duì)象的運(yùn)行時(shí)信息狐胎。這些內(nèi)省方法有助于找出對(duì)象在類層次中的位置鸭栖,確定對(duì)象是否實(shí)現(xiàn)特定的方法,以及測(cè)試對(duì)象是否遵循某種協(xié)議握巢。下面是部分方法
superclass和class方法(實(shí)現(xiàn)為類和實(shí)例方法)分別以Class對(duì)象的形式返回接收者的父類和類晕鹊。
您可以通過isKindOfClass:和isMemberOfClass:方法來確定對(duì)象屬于哪個(gè)類。后者用于測(cè)試接收者是否為指定類的實(shí)例暴浦。isSubclassOfClass:類方法則用于測(cè)試類的繼承性捏题。
respondsToSelector:方法用于測(cè)試接收者是否實(shí)現(xiàn)由選擇器參數(shù)標(biāo)識(shí)的方法。instancesRespondToSelector:類方法則用于測(cè)試給定類的實(shí)例是否實(shí)現(xiàn)指定的方法肉渴。
conformsToProtocol:方法用于測(cè)試接收者(對(duì)象或類)是否遵循給定的協(xié)議。
isEqual:和hash方法用于對(duì)象的比較带射。
description方法允許對(duì)象返回一個(gè)內(nèi)容描述字符串同规;這個(gè)方法的輸出經(jīng)常用于調(diào)試(“print object”命令),以及在格式化字符串中和“%@”指示符一起表示對(duì)象窟社。
對(duì)象的編碼和解碼
下面的方法和對(duì)象的編解碼(作為歸檔過程的一部分)有關(guān):
encodeWithCoder:和initWithCoder:是NSCoding協(xié)議僅有的方法券勺。前者使對(duì)象可以對(duì)其實(shí)例變量進(jìn)行編碼,后者則使對(duì)象可以根據(jù)解碼過的實(shí)例變量對(duì)自身進(jìn)行初始化灿里。
NSObject類中聲明了一些于對(duì)象編碼有關(guān)的方法:classForCoder:关炼、replacementObjectForCoder:、和awakeAfterUsingCoder:匣吊。
消息的轉(zhuǎn)發(fā)
forwardInvocation:允許一個(gè)對(duì)象將消息轉(zhuǎn)發(fā)給另一個(gè)對(duì)象儒拂。
消息的派發(fā)
在performSelector開頭的一些方法允許你延遲后派發(fā)指定消息,而且可以將消息(同步或異步的消息)從輔助線程派發(fā)到主線程色鸳。
對(duì)象的四種內(nèi)存管理方式社痛,如下圖所示
對(duì)象的生命周期—簡(jiǎn)化視圖
保持接收到的對(duì)象
拷貝接收到的對(duì)象
自動(dòng)釋放池
參考:
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