runtime各種數(shù)據(jù)結(jié)構(gòu)
對(duì)象
struct objc_object {
private:
isa_t isa;
public:
// ISA() assumes this is NOT a tagged pointer object
Class ISA();
// getIsa() allows this to be a tagged pointer object
Class getIsa();
...
}
所以說亚隙,只要是oc對(duì)象就有isa
指針,但是這句話也不完全對(duì)
并不是所有的oc對(duì)象都有isa指針肠牲,例如Tagged Pointer對(duì)象沒有isa指針幼衰,具體可以看這個(gè)文章深入理解Tagged Pointer
isa
指針是指向一個(gè)類對(duì)象,為啥說的類對(duì)象缀雳,我們接著看類的數(shù)據(jù)結(jié)構(gòu)
類
struct objc_class : objc_object {
// Class ISA;
Class superclass;
...
}
類的結(jié)構(gòu)體也是繼承對(duì)象的渡嚣,所以說類也是一個(gè)對(duì)象
這里理解可以看下
元類的文章,理解下元類,實(shí)例對(duì)象,類對(duì)象识椰,元類對(duì)象
協(xié)議
struct protocol_t : objc_object {
const char *mangledName;
// 這個(gè)協(xié)議遵循的協(xié)議
// 比如我們定義協(xié)議一般會(huì)xxDelete<NSObject>
struct protocol_list_t *protocols;
// 下面幾個(gè)看命名就知道什么意思了
method_list_t *instanceMethods;
method_list_t *classMethods;
method_list_t *optionalInstanceMethods;
method_list_t *optionalClassMethods;
property_list_t *instanceProperties;
...
}
1.協(xié)議的結(jié)構(gòu)體也是繼承objc_object
扬绪,說明協(xié)議也是對(duì)象
2.mangledName
是源于c++
的命名重整技術(shù),可以這樣簡單理解裤唠,c++
之所以可以方法重載是基于命名重整這個(gè)技術(shù)
print(int i)
print(char c)
這個(gè)技術(shù)簡單理解挤牛,就是編譯器,在底層重新給方法命名种蘸,比如上面的print墓赴,在底層可能會(huì)生成i_print
和c_print
分類
struct category_t {
// 所屬的類名,而不是Category的名字
const char *name;
// 所屬的類航瞭,這個(gè)類型是編譯期的類诫硕,這時(shí)候類還沒有被重映射
classref_t cls;
// 實(shí)例方法列表
struct method_list_t *instanceMethods;
// 類方法列表
struct method_list_t *classMethods;
// 協(xié)議列表
struct protocol_list_t *protocols;
// 實(shí)例屬性列表
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
// 類屬性列表
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};
因?yàn)闆]有成員變量列表,所以分類不可以添加成員變量刊侯,但是因?yàn)橛袑傩粤斜碚掳欤钥梢蕴砑訉傩?/p>
我們這里還發(fā)現(xiàn)了一個(gè)類屬性列表_classProperties
,
這個(gè)的用法是
@property (class, nonatomic, copy) NSUUID *identifier;
如果這樣聲明,xcode不會(huì)自動(dòng)生成set和get方法滨彻,你得自己實(shí)現(xiàn)藕届,而且你實(shí)現(xiàn)的get和set方法是類方法哦
這個(gè)是為了跟swift
交互誕生的
屬性
struct property_t {
const char *name;
const char *attributes;
};
// 測試代碼
@property (nonatomic, copy) NSString *string;
objc_property_t t = class_getProperty([self class],"string");
const char *name = property_getName(t);
const char *att = property_getAttributes(t);
NSLog(@"name:%s,att:%s",name, att);
// 輸出
name:string,att:T@"NSString",C,N,V_string
T代表類型@"NSString" 參考Type Encodings
C代表copy
N代表nonatomic
V代表實(shí)例變量_string
方法
struct method_t {
// 方法編號(hào)
SEL name;
// 參數(shù)和返回類型encode
const char *types;
// 函數(shù)指針
IMP imp;
// 根據(jù)方法名進(jìn)行方法排序(這個(gè)我也搞不懂用途)
struct SortBySELAddress :
public std::binary_function<const method_t&,
const method_t&, bool>
{
bool operator() (const method_t& lhs,
const method_t& rhs)
{ return lhs.name < rhs.name; }
};
};
成員變量
struct ivar_t {
int32_t *offset; // 偏移
const char *name; // 名字
const char *type; // 類型
// alignment is sometimes -1; use alignment() instead
uint32_t alignment_raw; // 對(duì)齊
uint32_t size; // 大小
uint32_t alignment() const {
if (alignment_raw == ~(uint32_t)0) return 1U << WORD_SHIFT;
return 1 << alignment_raw;
}
};