PS 一些关于runtime的小demo在我的下一篇文章[iOS-Runtime-实践篇](http://www.jianshu.com/p/d6a2656fc2cb)中
我们都知道Objective-C是一门动态语言,动态之处体现在它将许多静态语言编译链接时要做的事通通放到运行时去做,这大大增加了我们编程的灵活性。
毫不过分地说,Runtime就是OC的灵魂。接下来我就要拨开OC最外层的外衣,带大家看看OC的真面目(C/C++)。
类和对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@interface Person : NSObject { NSString *_name; int _age; } - (void)study; + (void)study; @end @implementation Person - (void)study { NSLog(@"instance - study"); } + (void)study { NSLog(@"class - study"); } @end |
为了更好地说明类在底层的表现形式是怎样, 我们将上面代码利用clang -rewrite-objc Person.m
指令将其用C/C++重写, 一窥究竟.
把不必要的删除, 整理后为下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// class的结构 struct _class_t { struct _class_t *isa; // isa指针 struct _class_t *superclass; // 父类 void *cache; void *vtable; struct _class_ro_t *ro; // class的其他信息 }; // class包含的信息 struct _class_ro_t { unsigned int flags; unsigned int instanceStart; unsigned int instanceSize; unsigned int reserved; const unsigned char *ivarLayout; const char *name; // 类名 const struct _method_list_t *baseMethods; // 方法列表 const struct _objc_protocol_list *baseProtocols; // 协议列表 const struct _ivar_list_t *ivars; // ivar列表 const unsigned char *weakIvarLayout; const struct _prop_list_t *properties; // 属性列表 }; // Person(class) struct _class_t OBJC_CLASS_$_Person = { .isa = &OBJC_METACLASS_$_Person, // 指向Person-metaclass .superclass = &OBJC_CLASS_$_NSObject, // 指向NSObject-class .cache = &_objc_empty_cache, 0, // unused, was (void *)&_objc_empty_vtable, &_OBJC_CLASS_RO_$_Person, // 包含了实例方法, ivar信息等 }; // Person(metaclass) struct _class_t OBJC_METACLASS_$_Person = { .isa = &OBJC_METACLASS_$_NSObject, // 指向NSObject-metaclass .superclass = &OBJC_METACLASS_$_NSObject, // 指向NSObject-metaclass .cache = &_objc_empty_cache, 0, // unused, was (void *)&_objc_empty_vtable, &_OBJC_METACLASS_RO_$_Person, // 包含了类方法 }; |
原来(显然), 我们的类其实就是一个结构体!!! 类跟我们的对象一样, 都有一个isa指针, 所以类其实也是对象的一种.
isa指针
isa指针非常重要, 对象需要通过isa指针找到它的类, 类需要通过isa找到它的元类. 这在调用实例方法和类方法的时候起到重要的作用.
实例对象在调用方法时, 首先通过isa指针找到它所属的类, 然后在类的缓存(cache)里找该方法的IMP, 如果没有, 则去类的方法列表中查找, 然后找到则调用该方法, 找不到则报错.
类对象调用方法则如出一辙, 通过isa指针找到元类, 然后就跟上述一致了. 这里涉及的发送消息机制下面会详细讲..
下面展示一些运行时动态获取对象和类的属性的C语言方法
类和类名 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// 返回对象的类 Class object_getClass ( id obj ); 6a2656fc2cb)中 我们都知道Objective-C是一门动态语言,动态之处体现在它将许多静态语言编译链接时要做的事通通放到运行时去做,这大大增加了我们编程的灵活性。 毫不过分地说,Runtime就是OC的灵魂。接下来我就要拨开OC最外层的外衣,带大家看看OC的真面目(C/C++)。 类和对象
为了更好地说明类在底层的表现形式是怎样, 我们将上面代码利用 把不必要的删除, 整理后为下面
原来(显然), 我们的类其实就是一个结构体!!! 类跟我们的对象一样, 都有一个isa指针, 所以类其实也是对象的一种. isa指针isa指针非常重要, 对象需要通过isa指针找到它的类, 类需要通过isa找到它的元类. 这在调用实例方法和类方法的时候起到重要的作用.
实例对象在调用方法时, 首先通过isa指针找到它所属的类, 然后在类的缓存(cache)里找该方法的IMP, 如果没有, 则去类的方法列表中查找, 然后找到则调用该方法, 找不到则报错. 类对象调用方法则如出一辙, 通过isa指针找到元类, 然后就跟上述一致了. 这里涉及的发送消息机制下面会详细讲.. 下面展示一些运行时动态获取对象和类的属性的C语言方法 类和类名 :
|