今天我們經過原始碼的探索來分析下類的結構,我們從isa
和類的繼承
兩方面來分析:
我們先看乙個經典的走位圖:
我們來驗證下isa的走位:
首先我們先建立乙個lgperson
類然後用lldb
列印一驗證:
@inte***ce lgperson : nsobject
@end
intmain
(int argc,
const
char
* ar**)
isa總結:物件的isa 指向物件的類--> 物件的類的isa指向元類 ---> 元類的isa指向根元類 ---> 根元類的isa指向自己
從上面的經典走位圖裡面我們也可以看出類
和元類
的繼承關係:
類
繼承於父類
父類
繼承於根類
根類
繼承於nil
元類
繼承於父元類
父元類
繼承於根元類
根元類
繼承於根類
根類
繼承於nil
注
: 關於類的繼承我們要明白一點:例項物件之間是沒有繼承關係的
,只有類 之間才有繼承關係
。
通過下面的圖我們也可以看到例項物件之間是沒有繼承關係的
我們在上面的走位圖中發現,物件
和類
、元類
中都有isa
,這是為什麼呢? 這就引出了兩個結構體_objc_class
和_objc_object
,我們對mian.m
進行clang
編譯後我們會發現物件本質是乙個結構體
,他的底層會被編譯為nsobject_impl
而 這個nsobject_impl
,內部包含乙個class 定義的 isa
,而class 是有 objc_class 定義的
:
struct lgperson_impl
;struct nsobject_impl
;typedef
struct objc_class *class;
我們在原始碼中搜尋objc_class
,發現objc_class
繼承於_objc_object
,而_objc_object
裡面包含乙個預設的isa
:
struct objc_class : objc_object
}struct objc_class
從上面的原始碼我們也看出了,所有的物件
和類
都是從objc_object
繼承過來的,所以都一定有isa
.
我們先建立乙個lgperson
類,然後為它新增屬性
、成員變數
、例項方法
、類方法
都存在類資訊的那個部位:
@inte***ce lgperson : nsobject
@property
(nonatomic, strong) nsstring *name;-(
void
)sayhello;+(
void
@end
@implementation lgperson-(
void
)sayhello+(
void
nslog()
;}@end
探索之前我們先看下類資訊
裡面都包含哪些東西:
struct objc_class : objc_object
}
我們看到bits
是儲存類的資訊的,而bits
是有class_data_bits_t
定義的,那我們就看下class_data_bits_t
的原始碼:
struct class_data_bits_t
// **自動省略
}const class_ro_t *
safe_ro()
else
}// **自動省略
我們主要看下class_rw_t
和class_ro_t
:
struct class_rw_t
const property_array_t properties()
const
const protocol_array_t protocols()
const
}
我們現在用lldb
來列印下bits
裡面的資訊:
總結
:
我們來根據一段**來驗證一下:
//mark: - 分析類物件記憶體存在個數
void
lgtestclassnum()
看下列印結果:
發現這個幾個class 的位址
都是一樣的,說明類在記憶體裡面只存在乙份
。
objc_class 與 objc_object 有什麼關係?
結構體型別objc_class
繼承自objc_object
型別,其中objc_object
也是乙個結構體,且有乙個isa
屬性,所以objc_class
也擁有了isa
屬性
objc_object 與 物件的關係?
所有的物件
都來自nsobject
,但他們的底層都是來自objc_object
,所以物件
和objc_object
是繼承關係
Mybatis的底層原理分析
在分析底層原理之前,先看單獨使用mybatis時的執行流程 public class mybatistest 6.釋放資源 sqlsession.close is.close 以下是我通過debug除錯得到的結果 拋開我們使用mybatis時這幾步執行流程來說,在mybatis底層最重要的兩個物件就...
class底層原理分析
class 類名 會把類構造出來 實際上是 元類例項化產生類 這個物件 類例項化產生物件,一定是 類名 person 類是由type例項化產生,傳一堆引數 type 呼叫類的 init 方法 type type object or name,bases,dict object or name 類的名...
iOS底層原理總結 OC方法的本質
int main int argc,const char argv return 0 可以看出在我們進行lgperson初始化的時候,我們都知道會呼叫alloc,init.我這裡為了簡單只呼叫 new 但是底層不是像我們利用呼叫的,而是呼叫了乙個函式objc msgsend這就是我們訊息傳送的方法,...