runtime 一:类,对象,属性

The runtime system acts as a kind of operating system for the Objective-C language;

it’s what makes the language work;

struct objc_class {

Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__

Class super_class                      OBJC2_UNAVAILABLE;  // 父类

const char *name                        OBJC2_UNAVAILABLE;  // 类名

long version                            OBJC2_UNAVAILABLE;  // 类的版本信息,默认为0

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:需要注意的是在Objective-C中,所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass(元类),我们会在后面介绍它。

super_class:指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。

cache:用于缓存最近使用的方法。一个接收者对象接收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象。在实际使用中,这个对象只有一部分方法是常用的,很多方法其实很少用或者根本用不上。这种情况下,如果每次消息来时,我们都是methodLists中遍历一遍,性能势必很差。这时,cache就派上用场了。在我们每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果cache没有,才去methodLists中查找方法。这样,对于那些经常用到的方法的调用,但提高了调用的效率。

version:我们可以使用这个字段来提供类的版本信息。这对于对象的序列化非常有用,它可是让我们识别出不同类定义版本中实例变量布局的改变。

注:

objc 是对象操作;

class是类操作;

MenuView *menu = [[MenuView alloc] init];

[menu test];

//等同于:

MenuView *menu = [[MenuView alloc] init];

objc_msgSend(menu, @selector(test)); //objc_msgSend(receiver, selector, arg1, arg2, ...)

//类名

const char *name=  class_getName(menu.class);

//父类

Class superClass =  class_getSuperclass(menu.class);

//获取类占用空间大小

size_t size = class_getInstanceSize(menu.class);

//成员变量

unsigned int outCount = 0;

Ivar *ivars = class_copyIvarList(menu.class, &outCount);

for (int i=0; i

Ivar ivar = ivars[i];

NSLog(@"instance variable's name: %s at index: %d", ivar_getName(ivar), i);

}

free(ivars);

输出:

2016-06-08 15:12:54.944 DropDownMenuTest[3170:1160686] instance variable's name: _property1 at index: 0

2016-06-08 15:12:54.944 DropDownMenuTest[3170:1160686] instance variable's name: _property2 at index: 1

// 属性(包括类自身的属性)

objc_property_t * properties = class_copyPropertyList(menu.class, &outCount);

for (int i = 0; i < outCount; i++) {

objc_property_t property = properties[i];

NSLog(@"property's name: %s", property_getName(property));

}

free(properties);

输出:

2016-06-08 15:12:54.945 DropDownMenuTest[3170:1160686] property's name: property1

2016-06-08 15:12:54.945 DropDownMenuTest[3170:1160686] property's name: property2

//遍历方法

Method *methods = class_copyMethodList(menu.class, &outCount);

for (int i =0; i

Method m = methods[i];

NSLog(@"第 %d 个 Method: %s ",i, method_getName(m ));

}

free(methods);

输出:

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 0 个 Method: test1

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 1 个 Method: test2

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 2 个 Method: property1

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 3 个 Method: setProperty1:

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 4 个 Method: property2

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 5 个 Method: setProperty2:

2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605] 第 6 个 Method: .cxx_destruct

//方法实例 (先从cache中寻找方法,没有,再遍历方法列表)

Method test1 = class_getInstanceMethod(menu.class, @selector(test1));

if (test1 != NULL) {

NSLog(@"method Instance %s", method_getName(test1));

}

//获取方法的具体实现,下面有具体应用

IMP imp = class_getMethodImplementation(menu.class, @selector(test1));

//动态创建类

IMP test3IMP = class_getMethodImplementation(self.class, @selector(test3));

Class newClass = objc_allocateClassPair([MenuView class], "myMenu", 0);

//像类当中添加方法的实现

class_addMethod(newClass, @selector(test3), (IMP)test3IMP, "");

//在应用中注册由objc_allocateClassPair创建的类

objc_registerClassPair(newClass);

//监测一下方法添加成功了没有。

Method *methodList = class_copyMethodList(newClass, &outCount);

for (int i = 0 ; i

Method m = methodList[i];

NSLog(@" 看看方法添加进去了没有??,,,%s",method_getName(m));

}

//添加完方法后,再调用

id instance = [[newClass alloc] init];

objc_msgSend(instance, @selector(test3)); //或者[instance performSelector:@selector(test3)];

输出:2016-06-08 15:31:56.294 DropDownMenuTest[3290:1251605]  看看方法添加进去了没有??,,,test3

2016-06-08 15:31:56.295 DropDownMenuTest[3290:1251605] test3...

// 创建类实例

//    id class_createInstance ( Class cls, size_t extraBytes );

//    class_createInstance函数:创建实例时,会在默认的内存区域为类分配内存。

//    extraBytes参数表示分配的额外字节数。这些额外的字节可用于存储在类定义中所定义的实例变量之外的实例变量。

//    该函数在ARC环境下无法使用。

/**

以下在ARC环境下无法使用。

Person * p1 = [[Person alloc] init];

NSLog(@"p1 - %@", [p1 class]);

Class c1 = object_setClass(p1, [Dog class]);

NSLog(@"c1 - %@", [c1 class]);

NSLog(@"p1 - %@", [p1 class]);

输出:  Person

Person

Dog

NSObject *a = [[NSObject alloc] init];

id newB = object_copy(a, class_getInstanceSize(MyClass.class));

object_setClass(newB, MyClass.class);//把类newB 修改成MyClass类型

object_dispose(a);

**/

objc_property_t property = class_getProperty([MenuView class], [@"property1" UTF8String]);

NSLog(@"====>>>%s", property_getName(property));

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容