一、SEL
1、什么是SEL
@selector()就是取类方法的编号,他的行为基本可以等同C语言的中函数指针。
2、usage
声明了一个函数指针myLog
@interface ViewController ()
{
SEL myLog;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
myLog = @selector(myLogL);
//通过performSelector来执行方法
[self performSelector:myLog];//打印 “myLog”
}
-(void)myLogL{
NSLog(@"myLog");
}
3、SEL的应用
target——action设计模式.
@interface Mybutton : UIButton
-(void)addMyTarget:(id)target action:(SEL)action;
@end
@implementation Mybutton
{
SEL _action;
id _target;
}
-(void)addMyTarget:(id)target action:(SEL)action{
_target=target;
_action=action;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[_target performSelector:_action];
}
@end
viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
Mybutton * btn = [[Mybutton alloc]initWithFrame:CGRectMake(100, 100, 60, 60)];
btn.backgroundColor=[UIColor redColor];
[btn addMyTarget:self action:@selector(click)];
[self.view addSubview:btn];
}
-(void)click{
NSLog(@"点击了btn");
}
二、Runtime
1、什么是Runtime
RunTime简称运行时。
平时编写的OC代码, 在程序运行过程中, 其实最终都是转成了runtime的C语言代码。
需要导入这两个头文件:
#import <objc/message.h>
#import <objc/runtime.h>
2、oc在向一个对象发送消息时,发生了什么?
根据对象的isa指针找到类对象id,在查询类对象里面的methodLists方法函数列表,如果没有找到,在沿着superClass, 寻找父类,再在父类methodLists方法列表里面查询,最终找到SEL,根据id和SEL确认IMP(指针函数),在发送消息;
IMP=implement
三、KVO
1、什么是KVO
KVO(key-value-observing)是一种回调机制,在某个对象注册监听者后,在被监听的对象发生改变时,对象会发送一个通知给监听者,以便监听者执行回调操作。
在 MVC 设计架构下的项目,KVO 机制很适合实现 mode 模型和 view 视图之间的通讯。
2、pricinple
当观察某对象 A 时,KVO 机制动态创建一个对象A当前类的子类,并为这个新的子类重写了被观察属性 keyPath 的 setter 方法。setter 方法随后负责通知观察对象属性的改变状况。
3、usage
1)注册观察者
[self.myKVO addObserver:self forKeyPath:@"num" options:
NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
//第一个参数 observer:观察者 (这里观察self.myKVO对象的属性变化)
//第二个参数 keyPath: 被观察的属性名称(这里观察 self.myKVO 中 num 属性值的改变)
//第三个参数 options: 观察属性的新值、旧值等的一些配置(枚举值,可以根据需要设置,例如这里可以使用两项)
//第四个参数 context: 上下文,可以为 KVO 的回调方法传值(例如设定为一个放置数据的字典)
- 属性(keyPath)的值发生变化时,收到通知,调用以下方法:
//aaa:属性名称
//bbb:被观察的对象
//ccc:变化前后的值都存储在 ccc 字典中
//ddd:注册观察者时,context 传过来的值
-(void)observeValueForKeyPath:(NSString *)aaa ofObject:(id)bbb change:(NSDictionary<NSString *,id> *)ccc
context:(void *)ddd
{
}
4、实例
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.myKVO = [[myKVO alloc]init];
[self.myKVO addObserver:self forKeyPath:@"num" options:
NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
/*object的keyPath属性发生变化,就会调用此回调方法*/
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if([keyPath isEqualToString:@"num"] && object == self.myKVO) {
// 响应变化处理:UI更新(label文本改变)
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
/* 移除KVO */
[self.myKVO removeObserver:self forKeyPath:@"num" context:nil];
}
@end
5、KVC与KVO
KVC 就是键值编码(key-value-coding)。
KVC 的主要作用:
通过键值路径为对象的属性赋值。
通过键值路径获取属性的值。
[appleVC setValue:@"橘子" forKey:@"name"];
//对象A的属性是一个对象B,要设置对象B的属性
[person setValue:@"旺财" forKeyPath:@"dog.name"];
NSString *nameStr = [appleVC valueForKey:@"name"];
例子:没有办法直接访问内部
@implementation Person
{
NSInteger _height;
}
- (void)logHeight
{
NSLog(@"%ld",_height);
}
@end
[p setValue:@170 forKey:@"height"];
KVO 就是基于 KVC 实现的关键技术之一。
KVO 的作用:它通过 key path 观察对象的值,当值发生变化的时候会收到通知。
网友评论