国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

對象與元類對象

2019-11-09 18:11:02
字體:
來源:轉載
供稿:網友

1、類對象(class object)①類對象的實質我們知道了:類對象是由編譯器創建的,即在編譯時所謂的類,就是指類對象(官方文檔中是這樣說的: The class object is the compiled version of the class)。任何直接或間接繼承了NSObject的類,它的實例對象(instance objec)中都有一個isa指針,指向它的類對象(class object)。這個類對象(class object)中存儲了關于這個實例對象(instace object)所屬的類的定義的一切:包括變量,方法,遵守的協議等等。因此,類對象能訪問所有關于這個類的信息,利用這些信息可以產生一個新的實例,但是類對象不能訪問任何實例對象的內容。當你調用一個 “類方法” 例如 [NSObject alloc],你事實上是發送了一個消息給他的類對象。

②類對象和實例對象的區別當然有區別了,盡管類對象保留了一個類實例的原型,但它并不是實例本身。它沒有自己的實例變量,也不能執行那些類的實例的方法(只有實例對象才可以執行實例方法)。然而,類的定義能包含那些特意為類對象準備的方法–類方法( 而不是的實例方法)。類對象從父類那里繼承類方法,就像實例從父類那里繼承實例方法一樣。③類對象與類名在源代碼中,類對象由類名表示。在下面的例子中,Retangle類 用從NSObject那里繼承來的方法來返回類的版本號:int versionNumber = [Rectangle version];只有在消息表達式中作為接收者,類名才代表類對象。其他地方,你需要要求一個實例或者類返回class id。 響應class消息:id aClass = [anObject class];id rectClass = [Rectangle class];如同上面的例子顯示的那樣,類對象像其他對象一樣,也是id類型。

總之,類對象是一個功能完整的對象,所以也能被動態識別(dynamically typed),接收消息,從其他類繼承方法。特殊之處在于它們是由編譯器創建的,缺少它們自己的數據結構(實例變量),只是在運行時產生實例的代理。

2、元類對象(metaclass object)①元類對象的實質實際上,類對象是元類對象的一個實例!!元類描述了 一個類對象,就像類對象描述了普通對象一樣。不同的是元類的方法列表是類方法的集合,由類對象的選擇器來響應。當向一個類發送消息時,objc_msgSend會通過類對象的isa指針定位到元類,并檢查元類的方法列表(包括父類)來決定調用哪個方法。元類代替了類對象描述了類方法,就像類對象代替了實例對象描述了實例化方法。很顯然,元類也是對象,也應該是其他類的實例,實際上元類是根元類(root class’s metaclass)的實例,而根元類是其自身的實例,即根元類的isa指針指向自身。類的super_class指向其父類,而元類的super_class則指向父類的元類。元類的super class鏈與類的super class鏈平行,所以類方法的繼承與實例方法的繼承也是并行的。而根元類(root class’s metaclass)的super_class指向根類(root class),這樣,整個指針鏈就鏈接起來了!!

記住,當一個消息發送給任何一個對象, 方法的檢查 從對象的 isa 指針開始,然后是父類。實例方法在類中定義, 類方法 在元類和根類中定義。(根類的元類就是根類自己)。在一些計算機語言的原理中,一個類和元類層次結構可以更自由的組成,更深元類鏈和從單一的元類繼承的更多的實例化的類。Objective-C 的類方法 是使用元類的根本原因,在其他方面試圖在隱藏元類。例如 [NSObject class] 完全相等于 [NSObject self],所以,在形式上他還是返回的 NSObject->isa 指向的元類。 Objective-C語言是一組實用的折中方案。

有些不明白? 下面這個圖標可能會有些幫助:

綜上所述,類對象(class object)中包含了類的實例變量,實例方法的定義,而元類對象(metaclass object)中包括了類的類方法(也就是C++中的靜態方法)的定義。類對象和元類對象中當然還會包含一些其它的東西,蘋果以后也可能添加其它的內容,但對于我們只需要記住:類對象存的是關于實例對象的信息(變量,實例方法等),而元類對象(metaclass object)中存儲的是關于類的信息(類的版本,名字,類方法等)。要注意的是,類對象(class object)和元類對象(metaclass object)的定義都是objc_class結構,其不同僅僅是在用途上,比如其中的方法列表在類對象(instance object)中保存的是實例方法(instance method),而在元類對象(metaclass object)中則保存的是類方法(class method)。關于元類對象可以參考蘋果官方文檔" The Objective-‐C PRogramming Language "

4、類對象和元類對象的相關方法

①object_getClass跟隨實例的isa指針,返回此實例所屬的類,對于實例對象(instance)返回的是類(class),對于類(class)則返回的是元類(metaclass),②-class方法對于實例對象(instance)會返回類(class),但對于類(class)則不會返回元類(metaclass),而只會返回類本身,即[@"instance" class]返回的是__NSCFConstantString,而[NSString class]返回的是NSString。③class_isMetaClass可判斷某類是否為元類.                                     

④使用objc_allocateClassPair可在運行時創建新的類與元類對,使用class_addMethod和class_addIvar可向類中增加方法和實例變量,最后使用objc_registerClassPair注冊后,就可以使用此類了。看到動態語言牛逼的地方了嗎,可以在需要時更改已經定義好的類!Objective-C的類別方法估計底層就是這么實現的,只是不知道為什么類別不能增加實例變量,有高手請留言。

5、因為在編譯的時候就為每個類分配了內存空間大小,根據他們的屬性,而且這些屬性直接保存在名objc_ivar_list的struct容器里,一旦編譯后就不鎖定了大小,所以不能在運行時隨意增加,也沒有空間再分給他們。之所以category可以是因為他的方法是存在名為objc_method_list的指針指向的struct容器里,由此可以看出屬性是全部都是丟在類里,而方法只是把裝他們的容器的地址丟在類里,所以屬性不能擴展,而方法可以無限制,因為他的大小不影響類的空間。參考文章http://blog.csdn.net/wzzvictory/article/details/8592492

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 谷城县| 建平县| 准格尔旗| 贡山| 云阳县| 临朐县| 金门县| 五寨县| 蒙阴县| 江口县| 叶城县| 永泰县| 富宁县| 兴海县| 桑植县| 洛宁县| 龙江县| 太保市| 刚察县| 抚远县| 湟源县| 临猗县| 凤凰县| 黑水县| 通辽市| 南京市| 镇平县| 云安县| 盐亭县| 云林县| 南充市| 平邑县| 盈江县| 含山县| 时尚| 横山县| 连云港市| 酒泉市| 永年县| 壶关县| 阿图什市|