电竞比分网-中国电竞赛事及体育赛事平台

分享

objc/runtime 探索(三)

 最初九月雪 2016-01-31

前言

續(xù)前,本文主要談?wù)擃愔械淖兞亢蛯傩?/p>

1.Ivar

1.1 Ivar的類型

typedef objc_ivar * Ivar;

struct objc_ivar {
	char *ivar_name;      	//ivar名稱                          
	char *ivar_type;        //ivar類型
	int ivar_offset;		//ivar偏移量
	#ifdef __LP64__
    	int space;
	#endif
}//ObjC2.0 已過時

Ivarobjc_ivar的指針,包含變量名稱,變量類型等成員.

1.2 為類添加Ivar

運行時規(guī)定,只能在objc_allocateClassPairobjc_registerClassPair兩個函數(shù)之間為類添加變量

如下所示:

//額外空間     未知,通常設(shè)置為 0
Class clazz = objc_allocateClassPair(父類class,類名,額外空間);
//以NSString*為例
//變量size sizeof(NSString)
//對齊     指針類型的為log2(sizeof(NSString*))
//類型     @encode(NSString*)
BOOL flag = class_addIvar(clazz,變量名,變量size,對齊,類型);
objc_registerClassPair(clazz);

1.3 Ivar的相關(guān)操作

//獲取Ivar的名稱
const char *ivar_getName(Ivar v);
//獲取Ivar的類型編碼,
const char *ivar_getTypeEncoding(Ivar v)
//通過變量名稱獲取類中的實例成員變量
Ivar class_getInstanceVariable(Class cls, const char *name)
//通過變量名稱獲取類中的類成員變量
Ivar class_getClassVariable(Class cls, const char *name)
//獲取指定類的Ivar列表及Ivar個數(shù)
Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
//獲取實例對象中Ivar的值
id object_getIvar(id obj, Ivar ivar) 
//設(shè)置實例對象中Ivar的值
void object_setIvar(id obj, Ivar ivar, id value)

1.4 Ivar的使用

//在運行時創(chuàng)建繼承自NSObject的People類
Class People = objc_allocateClassPair([NSObject class], "People", 0);
//添加_name成員變量
BOOL flag1 = class_addIvar(People, "_name", sizeof(NSString*), log2(sizeof(NSString*)), @encode(NSString*));
if (flag1) {
    NSLog(@"NSString*類型  _name變量添加成功");
}
//添加_age成員變量
BOOL flag2 = class_addIvar(People, "_age", sizeof(int), sizeof(int), @encode(int));
if (flag2) {
    NSLog(@"int類型 _age變量添加成功");
}
//完成People類的創(chuàng)建
objc_registerClassPair(People);
unsigned int varCount;
//拷貝People類中的成員變量列表
Ivar * varList = class_copyIvarList(People, &varCount);
for (int i = 0; i<varCount; i++) {
    NSLog(@"%s",ivar_getName(varList[i]));
}
//釋放varList
free(varList);
//創(chuàng)建People對象p1
id p1 = [[People alloc]init];
//從類中獲取成員變量Ivar
Ivar nameIvar = class_getInstanceVariable(People, "_name");
Ivar ageIvar = class_getInstanceVariable(People, "_age");
//為p1的成員變量賦值
object_setIvar(p1, nameIvar, @"張三");
object_setIvar(p1, ageIvar, @33);
//獲取p1成員變量的值
NSLog(@"%@",object_getIvar(p1, nameIvar));
NSLog(@"%@",object_getIvar(p1, ageIvar));

2.Property

2.1 objc_property_t 與 objc_property_attribute_t類型

typedef struct objc_property *objc_property_t;

//特性
typedef struct {
const char *name;           //特性名稱
const char *value;          //特性的值
} objc_property_attribute_t;

特性相關(guān)編碼

屬性的特性字符串 以 T@encode(type) 開頭, 以 V實例變量名稱 結(jié)尾,中間以特性編碼填充,通過property_getAttributes即可查看

特性編碼 具體含義
R readonly
C copy
& retain
N nonatomic
G(name) getter=(name)
S(name) setter=(name)
D @dynamic
W weak
P 用于垃圾回收機制

2.2 為類添加Property

BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)

2.3 Property的相關(guān)操作

//替換類中的屬性
void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount)
//獲取類中的屬性
objc_property_t class_getProperty(Class cls, const char *name)
//拷貝類中的屬性列表
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
//獲取屬性名稱
const char *property_getName(objc_property_t property)
//獲取屬性的特性
const char *property_getAttributes(objc_property_t property) 
//拷貝屬性的特性列表
objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount)
//拷貝屬性的特性的值
char *property_copyAttributeValue(objc_property_t property, const char *attributeName)

2.4 Property的使用

Class People = objc_allocateClassPair([NSObject class], "People", 0);
objc_registerClassPair(People);
//T@
objc_property_attribute_t attribute1;
attribute1.name = "T";
attribute1.value=@encode(NSString*);
//Noatomic
objc_property_attribute_t attribute2 = {"N",""};//value無意義時通常設(shè)置為空
//Copy
objc_property_attribute_t attribute3 = {"C",""};
//V_屬性名
objc_property_attribute_t attribute4 = {"V","_name"};
//特性數(shù)組
objc_property_attribute_t attributes[] ={attribute1,attribute2,attribute3,attribute4};
//向People類中添加名為name的屬性,屬性的4個特性包含在attributes中
class_addProperty(People, "name", attributes, 4);
//獲取類中的屬性列表
unsigned int propertyCount;
objc_property_t * properties = class_copyPropertyList(People, &propertyCount);
for (int i = 0; i<propertyCount; i++) {
    NSLog(@"屬性的名稱為 : %s",property_getName(properties[i]));
    NSLog(@"屬性的特性字符串為: %s",property_getAttributes(properties[i]));
}
//釋放屬性列表數(shù)組
free(properties);

參考:

ObjC底層數(shù)據(jù)類型

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多