日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

object c中的多态

發布時間:2023/12/14 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 object c中的多态 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1,何為多態:不同對象可以訪問相同方法的能力或現象。
2,多態的優勢:不同的類對象可以使用習慣的調用方式;簡化了編程接口;實現類和實例的接口隔離。

動態綁定,多態,在C++中主要是指基類指針,調用繼承類所實現的虛方法。

在object C中, 有比較新的展現形式。
(一)消息機制
oc中的消息機制就是 一個動態綁定的過程,
? ? ? ? ? ?每個類實例的第一個字段isa指針,指向類的結構體定義,里面有函數列表,緩存函數列表,協議列表,類名,實例參數列表,實例大小.....。
? ? ? ? ? ?消息調用過程:編譯過程中會在函數調用的代碼處添加, obj_msgSend: 函數調用;程序運行期,此函數完成動態綁定的所有過程。按照編譯期改為 obj_msgSend 寫時,填入的調用類,被調用者類,和他們的函數列表,找到對應的IMP即函數指針,完成函數調用。
???????????objc_msgSend(receiver, selector, arg1, arg2, ...)

該消息函數做了動態綁定所需要的一切:

  • 它首先找到選標所對應的方法實現。因為不同的類對同一方法可能會有不同的實現,所以找到的方法實現依賴于消息接收者的類型。

  • 然后將消息接收者對象(指向消息接收者對象的指針)以及方法中指定的參數傳給找到的方法實現。

  • 最后,將方法實現的返回值作為該函數的返回值返回。


(二)delegate,protocol配合的觀察者模式,是oc中多態的最常見運用方式
觀察者注冊,符合某種protocol的id實例指針,
當被觀察者認為條件滿足是,通過實例指針id,去調用protocol規定的同一種方法即可。

不論多少個觀察者,只要都實現了protocol規定的方法,都可以完成調用,



Object-C難以理解的一些概念

1.object-c 怎么實現多態

答:多態是在runtime里面實現的,在編譯的時候,compiler把所有class的定義都存放在class 實例對象里面,class實例對象包含了class的父class 實例對象的地址,class方法的select id和地址, class變量的偏移等。所有new出來的object都是從NSObject繼承過來的,所以所有對象都自動包含了一個isa的指針,這個指針在調用alloc為object分配地址的時候被指向class對象的地址,在運行的時候,我們調用class 方法是通過給object發送消息

[myobj method]這樣的形式,但編譯器會把這句話替換成

id objc_msgSend(id theReceiver, SEL theSelector, ...)

第一個參數就是myobj,第二個參數是“method”這個字符串經過編碼以后得到的唯一值,apple在runtime的時候查找method都是用

selector來做的,這樣效率會比字符串比較的效率要高。

objc_msgSend這個函數的執行過程大概就是,從thereceiver(也就是myobj)里面得到isa的地址,這個地址指向前面講到的

編譯器生成的class的object實例的地址(具體的結構請參考The Objective-C Programming Language),然后比較方法的selector

如果找到了,就知道了method的地址,就直接調用了。


2.對象的method是怎么訪問對象 變量的?

答:在編譯期間,編譯器可以知道指定class的所有繼承關系,所以它也知道要生成的object包含的所有變量(包含了父類的)。這樣

它就能算出所有變量相對于oject的首地址的偏移。在運行的時候,我們這樣調用object 的方法:

[myobj method];

實際上編譯器會隱含的把myobj的地址傳遞給method,所謂第一個參數(這個就是隱含參數的概念,請參考apple object c的文檔)

這樣知道了object的首地址和變量的偏移,也就知道了變量的地址。


3。self和super關鍵字是怎么實現的?

答:這個是面對對象語言容易出錯的地方,必須要理解這兩個關鍵字的實現原理才能掌握他們的正確使用方法,請參考apple?

object c文檔中舉的例子來了解為什么非常容易出錯。

上面我們提到了method在被調用的時候,會被傳入隱含參數,第一個隱含參數就是object的地址,self實際上在編譯期間被替換成了

ojbect的地址,所以堆self發送的消息都是根標準流程一樣通過isa鏈找到method來執行。

super就不一樣,super關鍵字被編譯器替換成了

id objc_msgSendSuper(struct objc_super *super, SEL op,??...)

其中objc_super的結構是

struct objc_super
{
id receiver;
Class class;
};

注意到

objc_msgSendSuper



id objc_msgSend(id theReceiver, SEL theSelector, ...)的區別,多了一個Class class;

class實際上就指向了找到當前method的class 對象的實例。

所以在objc_msgSendSuper中查找方法是從參數class指向的class 實例對象的isa開始查找的,而不是從theReceiver也就是myobj

這個對象的isa開始查找的




總結

以上是生活随笔為你收集整理的object c中的多态的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。