iOS類本質探究(一)

咱們先來解釋一下蘋果官方給開發者提供的這張圖bash

20190621191847.jpg

例如咱們建立個本身的類 LWPerson *person = [[LWPerson alloc] init];每一個類都有本身的isa,它指向對應的了[LWPerson Class],[LWPerson Class]也有本身的isa,它則指向對應的元類meta;這裏解釋一下兩個問題spa

Q : Instance(類對象),class(類),meta(即meta-class元類) 裏面各存着這麼設計

A : Instance 存着一個isa指向class,還存着本身的成員變量;class裏存有isasuperclass,屬性、對象方法、協議、成員變量等;meta裏存在isa,superclass,類方法等;如圖(圖片引用自李明傑老師)3d

79a2f72d-1be5-45cc-b41e-c1392149501f.jpg
Q : 爲何 isa要這樣指來指去,這樣有什麼好處

A : 例如這段代碼指針

LWPerson *person = [[LWPerson alloc] init]; 
 person.age = 20;
 persom.height = 180;
 [person  sing];
 [person dance];
 [person rap];
複製代碼

其中ageheight都是每一個LWPerson私有的,每建立一個LWPerson均可能不同,可是singdancerap方法是每個LWPerson共有。因此當建立LWPerson對象後,只需isa和成員變量,全部的方法都放在LWPerson的類裏,對象經過isa找到對應類的的方法,這樣能夠大大的節省LWPerson對象所佔用的內存。這裏LWPerson類的isa指向LWPerson的元類,類方法就存在元類裏,也很好的解釋了通常狀況下 類方法爲何不能使自己的成員變量,由於存在類對象上;code

接回以前的繼續說:每一個類都存有一個superclass指針,這很好理解,子類若是找不到對應的方法,便會順着superclass指針找到對應的父類。meta的也同樣自己沒有的類方法也會去尋找父類的類方法,這樣一直一級一級往上傳,一直傳到Root Class, Root Class的元類比較特殊,蘋果設計它的isa指向本身,superclass指向Root Class,若是Root Class也找不到方法,就會報一個咱們很熟悉的錯誤 unrecognized selector sent to instance 0x600001a3a5b0cdn

可能上面說的比較多比較亂,咱們能夠舉個栗子再捋一次 首先,咱們建立個類LWPerson繼承於NSObject對象

LWPerson *person = [[LWPerson alloc] init];
複製代碼

在建立LWPerson的時候,咱們用的[LWPerson alloc]本質就是 LWPerson類經過isameta裏找類方法,可是找不到!就再經過metasuperclass找到它的父metaNSObjectmeta, NSObject的類方咱們很容易就能夠找到allocinit也是同理,咱們在[LWPerson alloc]後,它實際上返回的是一個LWPerson的對象,它自己也沒有init對象方法,因此找它的父類NSObject 的對象方法init blog

20190621192701.jpg

咱們也能夠在LWPerson.h中聲明一個-(void)sing方法,但不寫實現,這樣person對象就會去LWPerson的類裏找sing方法,但沒實現sing方法,就會順着superclassNSObject到對象方法,但NSObject也沒有sing方法,因此繼續往上找到了Root Class,但Root Class也沒有sing方法,因此指向nil,系統報錯 unrecognized selector sent to instance繼承

20190621192643.jpg
這就是方法系統調用的過程,固然還有很多更底層更細緻的流程,篇幅緣由就下次再細聊了
相關文章
相關標籤/搜索