KVO:对属性进行监听。
HMPerson *p =[[HMPerson alloc]init];
@property(nonatomic,strong)HMPerson *p;
self.p = p;
//让self不要再监听age的属性了
-(void)dealloc
{
[self.p removeObserve:self forKeyPath:@"age"];
}
p.age = 20;
[p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld context:nil]
p.age = 30;
当p.age的属性发生改变时,就会调用下面的方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
}
KVO的内部实现 :
会在内部实现一个基类的派生类,在子类里面重写了setAge的方法,然后在内部实现监听的方法
运行时机制:runtime
runtime:是一套底层的C语言API(包含很多强大实用的C语言数据类型,C语言函数)
实际上,平时我们编写的OC代码,底层都是基于runtime实现的,
也就是说,平时我们编写的OC代码,最终都是转成了底层的runtime代码(c语言代码)
runtime有什么用:
1,能动态产生一个类,一个成员变量,一个方法。
2,能动态的修改一个类,一个成员变量,一个方法。
3,能动态的删除一个类,一个成员变量,一个方法。
[[UIDevice currentDevice].systemVersion floatValue]>=7.0
self.iconView.image = [UIImage imageNamed:@"face_os7"];
什么是IOS Swizzle?
常见的函数,头文件
#import<objc/runtime.h> : 成员变量,类,方法。
class_copyIvarList: 获得某个类内部的所有成员变量。
class_copyMethodList: 获得某个类内部的所有方法。
class_getInstanceMethod:获得某个具体的实例方法(对象方法,减号—开头)。
class_getClassMethod:获得某个具体的类方法(加号+开头)。
method_exchangeImplementations:交换2个方法的实现。
#import<objc/message.h> : 消息机制。
利用运行时函数交换2个方法的实现
只要分类被装载到内存中,就会调用1次。
KVC:间接通过字符串类型的key取出对应的属性值(可以访问私有的属性)。
KVC的价值:
1,可以访问私有成员变量的值。
2,可以间接修改私有成员变量的值(替换系统自带的导航栏,tabbar)。访问get方法
id类型 不能用点语法的。
-(id)init
{
if(self =[super init]){
_height = 1.555;
}
return self;
}
@private int _height;
float h1= [[p valueForKey:@"height"] floatValue];
float h2= [[p valueForKeyPath:@"height"] floatValue];
NSLog(@"%f,%f",h1,h2);
key就是属性
valueForKey与valueForKeyPath的区别:
valueForKeyPath包含了valueForKey的功能。
valueForKey:只能访问当前对象的属性。
valueForKeyPath:能利用,运算符一层一层往内部访问属性。(人的狗的名字)
p.books = @[b1,b2,b3];
[p valueForKeyPath:@"books.@count"]//计算数组的长度
NSArray *name = [p valueForKeyPath:@"books.name"];