OC對象的本質(zhì)(上):OC對象的底層實現(xiàn)原理
OC對象的本質(zhì)(中):OC對象的種類
OC對象的本質(zhì)(下):詳解isa&superclass指針
Objective-C中的對象,簡稱OC對象,主要分3類
-
instance
對象(實例對象) -
class
對象(類對象) -
meta-class
對象(元類對象)
instance 實例對象
instance
對象就是通過alloc
方法創(chuàng)建出來的對象,每次調(diào)用alloc
方法都會生成新的instance對象
NSObjcet *object1 = [[NSObject alloc] init];
NSObjcet *object2 = [[NSObject alloc] init];
上面的object1
object2
都是NSObject的instance對象(實例對象),因為他們都有自己的獨有內(nèi)存,所以是兩個不同的對象
instance
對象在內(nèi)存中存放的信息包括
-
isa
指針(因為基本上我們常用的類以及自定義類都繼承自NSObject
,所以我們這里討論的instance
里面都包含isa
指針) - 其他
成員變量
class 類對象
class
對象的作用是用來描述一個instance
對象,它內(nèi)部存放一個類的屬性信息(@property
)、對象方法信息(instance method
)、協(xié)議信息(protocol
)、成員變量信息(ivar
),另外class對象里面還有兩個指針,isa
指針 和superclass
指針。
可以通過一下方法,獲取一個類的類對象
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
Class objClass1 = [NSObject class];
Class objClass2 = [obj1 class];
Class objClass3 = [obj2 class];
Class objClass4 = object_getClass(obj1);
Class objClass5 = object_getClass(obj2);
//一個類在內(nèi)存中只存一份
NSLog(@"\nobjClass1:%p\nobjClass2:%p\nobjClass3:%p\nobjClass4:%p\nobjClass5:%p",
objClass1,
objClass2,
objClass3,
objClass4,
objClass5);
}
return 0;
}
如上圖打印結(jié)果,可以看出,一個類的類對象是唯一的,在內(nèi)存中只存一份,這也很好理解,因為類對象中的信息只需要一份就夠了。
meta-class 元類對象
meta-class
對象的作用是用來描述一個class
對象。跟class
一樣,元類對象在內(nèi)存中也是只有一份的。它內(nèi)部存儲了isa
指針 +superclass
指針 + 類方法信息(+方法)
下面是元類對象一些相關(guān)的api:
-
object_getClass(<class對象>);
獲取元類對象,參數(shù)為一個類對象 -
class_isMetaClass(<class對象/meta-class對象>);
判斷是否是元類對象
因為class
和meta-class
對象都可以通過object_getClass
獲得,因此他們的類型都是一樣的,都是typedef struct objc_class *Class
這個Class
類,可以理解,它們各自利用Class
的一些成員變量來實現(xiàn)自己的功能。
幾個常用方法的區(qū)別
(a)
Class objc_getClass(const char *aClassName)
- 入?yún)⑹且粋€字符串,也就是類名
- 返回值是對應(yīng)的
class對象
- 因為我們通過字符串,只能定義類的名字,所以這個方法只能返回
class對象
(b)
Class object_getClass(id obj)
- 入?yún)?code>obj可以是
instance對象
、class對象
或者meta-class對象
- 返回值
- 傳入
instance對象
,返回對應(yīng)的class對象
- 傳入
class對象
,返回對應(yīng)的meta-class對象
- 傳入
meta-class對象
,返回NSObject(基類)
的meta-class對象
- 傳入
/***********************************************************************
* object_getClass.
* Locking: None. If you add locking, tell gdb (rdar://7516456).
**********************************************************************/
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
根據(jù)上面的object_getClass
的源碼實現(xiàn),我們看到,這個方法返回的是isa
指針。
我用僅有的一點美術(shù)功底,手繪描述了一下各種isa
間的關(guān)系,所以根據(jù)instance
的isa
可以得到它的class
對象,根據(jù)class
的isa
指針,可以得到它的meta-class
對象,至于meta-class的
isa`指針問題,我們留到下一章仔細(xì)論述。
(c)
- (Class)class
&+ (Class)class
一個類的實例方法和類方法里面都有這個方法。我們用代碼來測試一下
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj1 = [[NSObject alloc] init];
Class objClass1 = [NSObject class];
Class objClass2 = [obj1 class];
Class objClass3 = [objClass1 class];
Class objClass4 = [objClass2 class];
//一個類在內(nèi)存中只存一份
NSLog(@"\nobjClass1:%p\nobjClass2:%p\nobjClass3:%p\nobjClass4:%p",
objClass1,
objClass2,
objClass3,
objClass4);
}
return 0;
}
輸出結(jié)果如下
根據(jù)結(jié)果,我們可以總結(jié)出,一個
class對象
調(diào)用(Class)class
方法,返回的不是它的meta-class對象
,而是它自身。總之,不論- (Class)class
還是 + (Class)class
,都只能返回一個類的`class對象
OC對象的本質(zhì)(上):OC對象的底層實現(xiàn)
OC對象的本質(zhì)(中):OC對象的分類
OC對象的本質(zhì)(下):詳解isa&superclass指針