對象(Object): OC中基本構造單元 (building block),用於存儲和傳遞數據。
可以在objc.h的文件中查找到對象結構的定義,如下所示即對象結構為Class類型的isa,而Class是 objc_class結構類型指針。objc_class即我們理解的類對象結構,其也包含一個isa類對象結構指針。
類和對象的最終實現都是一種數據結構,(subclass is an instance of superclass)
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
id類型定義
/// A pointer to an instance of a class.
typedef struct objc_object *id;
Class類型定義
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
類(對象)結構
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
一個完整的類應該包括類方法、實例方法和成員變量(實例變量), 每個對象都包括一個isa(is a class)指針指向類對象(運行時方法發送給對象消息,才確定類別並調用相應的方法實現
),類對象結構中記載了類的所有信息。
類對象的isa指向元類對象(meta class),類對象中的方法列表是實例方法(-, instance methods), 元類對象中的方法列表是類方法(+, class methods)
可以這麼理解:類包括類對象和元類對象,它們通過類對象結構定義,構成類的所有信息。在定義實例對象的時候,並不會進行任何存儲空間(堆)分配,直到調用類方法alloc函數和實例方法init函數實現實例對象在堆中的結構存儲分配,並將isa指向其類對象,父類成員變量和對應類對象成員變量初始化為0或nil
#import
#import
@interface AClass : NSObject
{
int a;
char cA;
}
- (void)printA;
@end
@implementation AClass
- (void)printA
{
NSLog(@I am class A~);
}
@end
@interface BClass : AClass
{
int b;
char cB;
}
- (void)printB;
@end
@implementation BClass
- (void)printB
{
NSLog(@I am class B~);
}
@end
// ---------- main ----------
int main(int argc, const char * argv[]) {
@autoreleasepool {
// ******對象模型初探******
AClass *a = [[AClass alloc] init];
BClass *b = [[BClass alloc] init];
BClass *b1;
[a printA];
[b printB];
}
return 0;
}
查看對象變量結構(通過設置斷點進入Debug模式查看)
類對象、元類和實例對象的isa指針調用圖示<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPqOoc3ViY2xhc3MgaXMgYSBpbnN0YW5jZSBvZiBzdXBlcmNsYXNzo6kNCjxwPigxKSBSb290IGNsYXNzIMrHTlNPYmplY3SjrCBOU09iamVjdMO709CzrMDgo6xzdXBlcmNsYXNzIKOtJmd0OyBuaWw8L3A+DQo8cD4oMikgw7+49sDgttTP87a809DSu7j2aXNh1rjP8s6o0ru1xE1ldGEgY2xhc3M8L3A+DQo8cD4oMykgw7+49tSqwOC21M/ztcQgaXNh1rjV67a81rjP8iBOU09iamVjdLXE1KrA4LbUz/M8YnIgLz4NCjxpbWcgYWx0PQ=="這裡寫圖片描述" src="http://www.bkjia.com/uploads/allimg/150723/0434401T6-1.jpg" title="\" />
消息傳遞(Messaging): 在對象之間傳遞數據並執行任務的過程
Objective-C基於C語言加入了面向對象特性和消息轉發機制的動態語言,除編譯器外還需要用Runtime系統來動態創建類和對象進行消息發送和轉發。
不同語言有不同函數傳遞方法,C語言 - 函數指針,C++ - 函數調用(引用)類成員函數在編譯時候就確定了其所屬類別, Objective-C 通過選擇器和block。
Objective-C強調消息傳遞而非方法調用。可以向一個對象傳遞消息,且不需要再編譯期聲明這些消息的處理方法。這些方法在運行時才確定。運行時(runtime)具體功能將在下面介紹。
[receiver message];
並不會馬上執行 receiver 對象的 message方法的代碼,而是向receiver發送一條message消息,該句話被編譯器轉化為:
id obj_msgSend(id self, SEL op, …);
PS: 消息調用函數還存在特殊情況,如其他函數
objc_msgSend_stret //待發送消息返回結構體
objc_msgSend_fpret //返回浮點數
objc_msgSendSuper //給超類發消息
SEL 表示方法選擇器,結構如下: typedef struct objc_selector*SEL;
, 可通過關鍵字@selector()獲得
id 數據結構在第一部分:對象模型
中已經有定義。
obj_msgSend 發消息流程:
Method數據結構
runtime.h頭文件中定義:
typedef struct objc_method *Method;
struct objc_method {
SEL method_name; // 特殊的字符串,描述方法名, 可以通過關鍵字 @selector( ) 獲取
char *method_types;
IMP method_imp;
}
PS:消息轉發分為兩大階段即動態添加方法解析(dynamic method resolution)和完整的消息轉發機制(full forward mechanism)
runtime : 程序運行後,提供相關支持的代碼叫做OC運行期環境(OC runtime)
,它提供了對象間傳遞消息的重要函數(比如objc_msgSend),並且包含創建類實例所用的全部邏輯(即創建實例對象的存儲結構和空間,包括isa指向“類對象”的指針)
runtime系統是一個用C語言編寫動態鏈接庫,核心是消息分發。Runtime機制包括對象模型,消息傳遞和轉發,方法實現機制和其他運行時方法,可以實現動態創建修改類對象和對象等功能,消息傳遞和轉發,方法動態實現,Method Swizzling等功能。