OC 中的动态性。
OC语言的动态性主要体现在三个方面:动态类型(Dynamic typing)、动态绑定(Dynamic binding)和动态加载(Dynamic loading)。
在这里我不是要说动态,而是探究一下 继承 中属性(property)和方法(method),的动态加载是如何实现的。
首先runtime 获取class 和 child class 的 属性列表 和方法列表,来看看会怎么样?
先看代码:
@interface Animal : NSObject
@property(nonatomic,strong)NSString *name;
- (void)eat;
@end
@interface Cat : Animal
@end
Animal *animal = [[Animal alloc]init];
[animal eat];
Animal *cat = [[Cat alloc]init];
[cat eat];
cat 是 Animal 的子类,基本的动态性。但我能聊得这么那个吗?
先把问题讲出来啊
问题1:继承中子类是在如何绑定父类的属性的?
-(void)getProperties{
u_int count = 0;
objc_property_t *properties = class_copyPropertyList([Cat class], &count);
for (int i = 0; i < count; i++) {
const char *propertyName = property_getName(properties[i]);
NSString *str = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding];
NSLog(@"propertyName : %@", str);
}
}
我的天啊,木有什么也木有。cat 里面什么也没有。那个属性没有,name 在哪里?
问题2:继承中子类是在如何绑定父类的方法的?
- (void)getMethods{
unsigned int count;
Method *methods = class_copyMethodList([Cat class], &count);
for (int i = 0; i < count; i++) {
Method method = methods[i];
SEL selector = method_getName(method);
NSString *name = NSStringFromSelector(selector);
NSLog(@"method_getName:%@",name);
}
}
结果是:
精简版
method_getName:eat
method_getName:setName:
method_getName:name
有了有了,我的天啊。原来在这里。继承的子类cat里面并没有的父类的属性,但是系统直接给你写了setter 和getter 方法,这样你就可以self.name 了,所以_name 是不行的。
给出上边两个问题答案:
继承是动态的,只在子类中方法列表中添加了方法名,属性也是以添加setter和getter方法来实现的。
注意一点如果子类没有实现父类的方法,那么这个方法就在被添加进子类的方法列表的。
希望这些分享能对大家有帮助。