oc語言的特性 動(dòng)態(tài)類型識(shí)別打厘,動(dòng)態(tài)綁定,動(dòng)態(tài)加載

OC做為一門面向?qū)ο笳Z言贺辰,自然具有面向?qū)ο蟮恼Z言特性户盯,如封裝、繼承饲化、多態(tài)莽鸭。他具有靜態(tài)語言的特性(如C++),又有動(dòng)態(tài)語言的效率(動(dòng)態(tài)綁定吃靠、動(dòng)態(tài)加載等)硫眨。整體來說,確實(shí)是一門不錯(cuò)的編程語言巢块。
現(xiàn)在礁阁,讓我來想想OC的動(dòng)態(tài)語言特性巧号。OC的動(dòng)態(tài)特性表現(xiàn)為了三個(gè)方面:動(dòng)態(tài)類型、動(dòng)態(tài)綁定姥闭、動(dòng)態(tài)加載丹鸿。之所以叫做動(dòng)態(tài),是因?yàn)楸仨毜竭\(yùn)行時(shí)(run time)才會(huì)做一些事情棚品。
一靠欢、Objective-C多態(tài)
1.概念:相同接口,不同的實(shí)現(xiàn)
來自不同類可以定義共享相同名稱的方法铜跑。
動(dòng)態(tài)類型(id)能使程序直到執(zhí)行時(shí)才確定對(duì)象所屬類型
動(dòng)態(tài)類型綁定能使程序直到執(zhí)行時(shí)才確定要對(duì)對(duì)象調(diào)用的實(shí)際方法
2.Objective-C不同于傳統(tǒng)程序設(shè)計(jì)語言门怪,它可以再運(yùn)行時(shí)加入新的數(shù)據(jù)類型和新的程序模塊:動(dòng)態(tài)類型識(shí)別,動(dòng)態(tài)綁定疼进,動(dòng)態(tài)加載
3.id類型:通用指針類型薪缆,弱類型,編譯時(shí)不進(jìn)行類型檢查
二伞广、動(dòng)態(tài)類型識(shí)別
1.任意NSObject的子類都會(huì)繼承NSObject的isa實(shí)例變量,而且當(dāng)NSObject的子類實(shí)例化對(duì)象時(shí)疼电,isa實(shí)例變量永遠(yuǎn)是對(duì)象的第一個(gè)實(shí)例變量嚼锄。
2.類對(duì)象
*類對(duì)象再程序運(yùn)行時(shí)一直存在。
*類對(duì)象是一種數(shù)據(jù)結(jié)構(gòu)蔽豺,存儲(chǔ)類的基本信息:類大小区丑,類名稱,類的版本以及消息與函數(shù)的映射表等
*類對(duì)象所保存的信息在程序編譯時(shí)確定修陡,在程序啟動(dòng)時(shí)加載到內(nèi)存中沧侥。
*類對(duì)象代表類,class代表類對(duì)象魄鸦,類方法屬于類對(duì)象
*如果消息的接收者是類名宴杀,則類名代表類對(duì)象
*運(yùn)行時(shí),所有類的實(shí)例都由類對(duì)象生成拾因,類對(duì)象會(huì)把實(shí)例的isa的值修改成自己的地址旺罢,每個(gè)實(shí)例的isa都指向該實(shí)例的類對(duì)象,*從類對(duì)象里可以知道父類信息绢记、可以響應(yīng)的方法等
*類對(duì)象只能使用類方法扁达,不能用實(shí)例方法
3.SEL類型
Objective-C在編譯的時(shí)候,會(huì)根據(jù)方法的名字 (包括參數(shù)序列),生成一個(gè)用來區(qū)分這個(gè)方法的唯一的一個(gè)標(biāo)示(ID),這個(gè)標(biāo)示(ID)就是SEL類型的,在運(yùn)行時(shí)候是通過方法的標(biāo)示來查找方法的。只要方法的名字(包括參數(shù)序列)相同,那么它們的 ID都是相同的蠢熄」蚪猓可以通過@select()指示符獲得方法的標(biāo)示。SEL mydraw =@select(draw)签孔;
NSSelectorFromString(NSString);根據(jù)方法名得到方法標(biāo)識(shí)
(NSString
)NSStringFromSelector(SEL);得到SEL類型的方法名
4.動(dòng)態(tài)類型識(shí)別常用方法
-(BOOL)isKindOfClass:classObj 是否是classObj類或其子類
-(BOOL)isMemberOfClass:classObj是否是classObj的實(shí)例
-(BOOL)respondsTosSelector:selector 類中是否有這個(gè)方法
NSClassFromString(NSString*);由字符串得到類對(duì)象
NSStringFromClass([類名 Class]);由類名得到字符串
Class rectClass= [Rectangle class];通過類名得到類對(duì)象
Class aClass =[anObject class];通過實(shí)例得到類對(duì)象
if([obj1 class]== [obj2 class])判斷是不是相同類的實(shí)例

  1. 可以將對(duì)象分為id類型和靜態(tài)類型
  • 如果不涉及到多態(tài),盡量使用靜態(tài)類型
    – 靜態(tài)類型可更好的在編譯階段而不是運(yùn)行階段指 出錯(cuò)誤
    – 靜態(tài)類型能夠提高程序的可讀性
    三叉讥、動(dòng)態(tài)綁定
  1. 在objective-c中,一個(gè)對(duì)象內(nèi)否調(diào)用指定的方法不是由編譯器決定而是由運(yùn)行時(shí)決定,這被稱作是方法的動(dòng)態(tài)綁定砾跃。
  2. 在objective-c里,對(duì)象不調(diào)用方法,而是接收消息,消息 表達(dá)式為: [reciver message];運(yùn)行時(shí)系統(tǒng)首先確定接收者的類型(動(dòng)態(tài)類型識(shí)別),然 后根據(jù)消息名在類的方法列表里選擇相依的方法執(zhí)行,所 以在源代碼里消息也稱為選擇器(selector)
  3. 消息函數(shù)的作用:
    – 首先通過第一個(gè)參數(shù)的receiver,找到它的isa 指針,然 后在isa 指向的Class 對(duì)象中使用第二個(gè)參數(shù)selector 查 找方法;
    – 如果沒有找到,就使用當(dāng)前Class 對(duì)象中的新的isa 指針 到上一級(jí)的父類的Class 對(duì)象中查找;
    – 當(dāng)找到方法后,再依據(jù)receiver 的中的self 指針找到當(dāng)前 的對(duì)象,調(diào)用當(dāng)前對(duì)象的具體實(shí)現(xiàn)的方法(IMP),然后傳 遞參數(shù),調(diào)用實(shí)現(xiàn)方法。
    – 假如一直找到NSObject 的Class 對(duì)象,也沒有找到你調(diào) 用的方法,就會(huì)報(bào)告不能識(shí)別發(fā)送消息的錯(cuò)誤节吮。
  4. Objetive-C中的Method結(jié)構(gòu)
    struct objc_method{
    SEL method_name;//方法名
    char *method_types; //方法地址
    IMP method_imp; //方法地址(IMP)
    };
    typedefobjc_method Method;
  5. 什么是IMP
    – IMP是”implementation”的縮寫,它是objetive-C 方法 (method)實(shí)現(xiàn)代碼塊的地址,類似函數(shù)指針,通過它可以 直接訪問任意一個(gè)方法抽高。免去發(fā)送消息的代價(jià)。
  6. 獲取方法的IMP
    – -(IMP)methodForSelector:(SEL)aSelector;
    SEL print_sel =NSSelectorFromString(@“print:”);//獲得SEL IMP imp=[person methodForSelector:print_sel];//得到IMP imp(person,print_sel,@“*********”);//通過IMP直接調(diào)用方法 等效調(diào)用:[person print_sel:@“*********”];
    – imp的第一參數(shù)是對(duì)象自己(self),第二參數(shù)是方法標(biāo)示, 第三個(gè)是方法的參數(shù)
    四透绩、動(dòng)態(tài)加載:運(yùn)行時(shí)加載新類
    在運(yùn)行時(shí)創(chuàng)建一個(gè)新類,只需要3步:

1 類中每一個(gè)方法在內(nèi)部轉(zhuǎn)換后的結(jié)構(gòu)體
struct objc_method
{
SEL method_name; 函數(shù)名稱
char *method_types; 函數(shù)類型
IMP method_imp; 函數(shù)的具體實(shí)現(xiàn) 這里是一個(gè)指針翘骂,指向具體的實(shí)現(xiàn)
};
2 每一個(gè)類擁有的的函數(shù)列表
struct objc_method_list
{ struct objc_method_list *obsolete; 函數(shù)列表
int method_count; 類中函數(shù)的個(gè)數(shù)
struct objc_method method_list[1]; 函數(shù)列表中的第一個(gè)函數(shù)地址};
下面是函數(shù)具體的加載過程0. 定義一個(gè)函數(shù)

  1. 創(chuàng)建一個(gè)上面所說的objc_method結(jié)構(gòu)體的實(shí)例,顯然這個(gè)結(jié)構(gòu)體的實(shí)例是一個(gè)函數(shù)帚豪,內(nèi)部的參數(shù)由步驟0決定
    1.0 為結(jié)構(gòu)體的函數(shù)名method_name賦值碳竟;
    1.1 為結(jié)構(gòu)體的函數(shù)實(shí)現(xiàn)賦值。(函數(shù)指針指向(內(nèi)存代碼區(qū))具體的實(shí)現(xiàn))狸臣。
  2. 添加objc_method結(jié)構(gòu)體的實(shí)例到上面多說的第二個(gè)結(jié)構(gòu)體 objc_method_list中
  3. 調(diào)用class_addMethods方法莹桅,將objc_method_list添加到相應(yīng)的類里面

下面代碼示例:

import <objc/objc-class.h>

// create a class with no methods
@interface EmptyClass : NSObject { }
@end

@implementation EmptyClass
@end

// define the function to add as a method
id sayHello ( id self, SEL _cmd,... )
{
NSLog (@"Hello");
}

void addMethod ()
{
struct objc_method myMethod; <span style="white-space:pre"> </span>//0 創(chuàng)建method實(shí)例
myMethod.method_name = sel_registerName("sayHello"); <span style="white-space:pre"> </span>//1.0 為函數(shù)名賦值
myMethod.method_imp = sayHello; <span style="white-space:pre"> </span>//1.1 為函數(shù)實(shí)現(xiàn)賦值

struct objc_method_list * myMethodList;
myMethodList = malloc (sizeof(struct objc_method_list));
myMethodList->method_count = 1;
myMethodList->method_list[0] = myMethod;<span style="white-space:pre"> </span>//2 將自定義的函數(shù)實(shí)例添加到 list中

class_addMethods ( [EmptyClass class], myMethodList );//3 將list綁定到類上面

// 調(diào)用
EmptyClass * instance = [[EmptyClass alloc] init];
[instance sayHello];
[instance release];
}
這基本就是OC動(dòng)態(tài)加載的過程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烛亦,一起剝皮案震驚了整個(gè)濱河市诈泼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌煤禽,老刑警劉巖铐达,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異檬果,居然都是意外死亡瓮孙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門选脊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杭抠,“玉大人,你說我怎么就攤上這事恳啥∑樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵角寸,是天一觀的道長菩混。 經(jīng)常有香客問我,道長扁藕,這世上最難降的妖魔是什么沮峡? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮亿柑,結(jié)果婚禮上邢疙,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好疟游,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布呼畸。 她就那樣靜靜地躺著,像睡著了一般颁虐。 火紅的嫁衣襯著肌膚如雪蛮原。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天另绩,我揣著相機(jī)與錄音儒陨,去河邊找鬼。 笑死笋籽,一個(gè)胖子當(dāng)著我的面吹牛蹦漠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播车海,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼笛园,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了侍芝?” 一聲冷哼從身側(cè)響起研铆,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竭贩,沒想到半個(gè)月后蚜印,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赖舟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年财搁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡里烦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锥债,到底是詐尸還是另有隱情岸售,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布翰灾,位于F島的核電站缕粹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纸淮。R本人自食惡果不足惜平斩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咽块。 院中可真熱鬧绘面,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瘦馍,卻和暖如春歼秽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背情组。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工燥筷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呻惕。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓荆责,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亚脆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子做院,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評(píng)論 0 9
  • 我們常常會(huì)聽說 Objective-C 是一門動(dòng)態(tài)語言濒持,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢键耕?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,195評(píng)論 0 7
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,558評(píng)論 33 466
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 733評(píng)論 0 2
  • 每每在朋友圈看到“五年沒換過手機(jī)號(hào)的人”“十年沒換過手機(jī)號(hào)的人”怎么樣怎么樣的文章屈雄,本座往往只會(huì)呵呵一笑,然后拿起...
    C座SAMA閱讀 1,613評(píng)論 0 1