Objcet-C物件分類
Object - C物件主要分為以下三種類型,具體如下:
1、例項物件(instance物件)
instance就是通過類alloc出來的物件,每次呼叫alloc都會產生新的instance物件(物件是否一樣取決於其對應記憶體地址是否一樣)
補充如下所示:
NSObject* objFirst = [[NSObject alloc] init]; NSObject* objSecond = [[NSObject alloc] init]; NSLog(@"objFirst物件地址:%p --- objSecond物件地址:%p", objFirst, objSecond);
執行如上程式碼,最終列印如下所示:

objFirst---objSecond.png
這樣我們就可以說是objFirst 與 objSecond是兩個不同的物件,因為佔據2塊不同的記憶體
例項物件的儲存資訊
- isa指標
- 其他成員變數
2、類物件(Class物件)
每個類的記憶體中有且只有一個類物件
補充如下(在上述程式碼基礎上新增如下程式碼,這裡傳遞的引數為instance物件,獲取到的是instance對應的Class物件):
Class objFirstClass = [objFirst class]; Class objSecondClass = [objSecond class]; Class objFirst_runtime = object_getClass(objFirst); Class objSecond_runtime = object_getClass(objSecond); Class objClass = [NSObject class];//獲取類物件 NSLog(@"objFirstClass物件地址:%p\nobjSecondClass物件地址:%p\nobjFirst_runtime物件地址:%p\nobjSecond_runtime物件地址:%p\nobjClass物件地址:%p", objFirstClass, objSecondClass, objFirst_runtime, objSecond_runtime, objClass);
-
object_getClass 這個是runtime的函式,使用時需要匯入標頭檔案 #import <objc/runtime.h>
執行如上程式碼,最終列印如下所示:
圖片.png
可以看出,上面的Class 物件記憶體地址均相同,那就說明這都是同一個物件,這也驗證了每個類在記憶體中有且只有一個Class物件
類物件的儲存資訊
- isa指標
- superClass指標
- 類的屬性資訊(@property),類的物件方法資訊(即 - 開頭的方法method),類的協議資訊(protocol),類的成員變數資訊(ivar)
- 類的成員變數資訊(這裡需要區分instance物件中所包含的成員變數資訊)
- insatance物件中所包含的成員資訊是指對應的值(具體的值)
- Class物件中所包含的成員資訊是指對應的名稱,型別等
簡單程式碼如下:(具體表現為 25 是在instance物件中,int 型別 _age 這些資訊是在Class物件中,所以說Class物件中也是包含類的成員資訊):
- 類的成員變數資訊(這裡需要區分instance物件中所包含的成員變數資訊)
@interface Person : NSObject{ @public int _age; } @end @implementation Person -(void)setAge:(int) age{ _age = age; }
Person* person = [[Person alloc] init]; person -> _age = 25;
3、元類物件(meta-class物件)
每個類的記憶體中有且只有一個元類物件
補充如下(在上述程式碼基礎上新增如下程式碼,這裡引數一定要是Class物件,這樣獲取到的才是meta-class物件):
Class objFirst_meta = object_getClass([objFirst class]); Class objSecond_meta = object_getClass([objSecond class]); Class objc_meta = object_getClass([NSObject class]); NSLog(@"\nobjFirst_meta物件地址:%p\nobjSecond_meta物件地址:%p\nobjc_meta物件地址:%p", objFirst_meta, objSecond_meta, objc_meta);
執行如上程式碼,最終列印如下所示:

圖片.png
同樣的以上物件的地址均一致,也驗證了每個類在記憶體中有且只有一個meta - class物件
元類的儲存資訊
-
isa指標
-
superClass指標
-
類方法資訊(即 + 開頭的方法 method)
-
類物件/元類物件其實都是Class物件,所以他們的記憶體結構其實是一樣的,但是用途不一樣,主要體現在存貯的資訊不一樣,例如元類物件存貯的就是類方法資訊,而類物件儲存的就是類物件方法資訊等。。。
-
元類物件其實也可以看成是特殊的類物件
用一副圖很形象的可以表現出來,如下所示
Object - C 類結構圖.png
本文中的參考程式碼貼出如下所示,都相對比較簡單:
NSLog(@"----------------instance - start--------------------------"); //instance物件 NSObject* objFirst = [[NSObject alloc] init]; NSObject* objSecond = [[NSObject alloc] init]; NSLog(@"objFirst物件地址:%p\nobjSecond物件地址:%p", objFirst, objSecond); NSLog(@"----------------instance - end--------------------------"); NSLog(@"----------------Class - start--------------------------"); //Class物件 Class objFirstClass = [objFirst class]; Class objSecondClass = [objSecond class]; Class objFirst_runtime = object_getClass(objFirst); Class objSecond_runtime = object_getClass(objSecond); Class objClass = [NSObject class];//獲取類物件 NSLog(@"\nobjFirstClass物件地址:%p\nobjSecondClass物件地址:%p\nobjFirst_runtime物件地址:%p\nobjSecond_runtime物件地址:%p\nobjClass物件地址:%p", objFirstClass, objSecondClass, objFirst_runtime, objSecond_runtime, objClass); NSLog(@"----------------Class - end--------------------------"); NSLog(@"----------------meta-class - start--------------------------"); //這裡的引數必須是類物件 //meta-class物件 Class objFirst_meta = object_getClass([objFirst class]); Class objSecond_meta = object_getClass([objSecond class]); Class objc_meta = object_getClass([NSObject class]); NSLog(@"\nobjFirst_meta物件地址:%p\nobjSecond_meta物件地址:%p\nobjc_meta物件地址:%p", objFirst_meta, objSecond_meta, objc_meta); NSLog(@"----------------meta-class - end--------------------------");
如有疑問,歡迎私信,文中所述,希望可以幫助有需要的小夥伴,也算是簡單做一個整理,方便日後回顧。。。