Delegate
delegate 是委托模式,委托模式是将一件属于委托者做的事情,交给另外一个被委托者来处理。
一个标准的委托由以下的部分组成:
|
|
也就是说,People 是一个必须要满足 Feeder 这个协议的模型,那么它必须实现一个 feed 函数。在 Dog 这个对象创建的时候可以将其 delegate 成员:
|
|
比如我们需要捕获对于一个按钮相应的动作事件,我们可以通过下面的两步完成:
在创建 Button 时,将
UIControlEventTouchUpInside
这个对象绑定一个名为buttonHandler
的函数:1 2 3 4
- (void)createButton { UIButton *button = [[UIButton alloc] init]; [button addTarget:self action:@selector(buttonHandler:) forControlEvents:UIControlEventTouchUpInside]; }
然后
buttonHandler
则可以在我们自己的类中实现:1 2 3
- (void)buttonHandler:(UIButton *)button { // 点击按钮 }
Block
可以通过 typedef
定义一个 Block 类型,然后类似地实现。比如下面是定义和实现:
|
|
然后可以用下面的方式给 Dog 的 handler 赋值:
|
|
NSNotification
大部分情况下,前两者实现方式能解决大部分问题,但是有一些情况是无法解决的,比如:
- 一对多。依赖关键远(比如两个页面间的通信)
于是需要用到 NSNotification
这样一个通知系统,这个通知系统的使用主要有以下三步:
添加通知:
1
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationFirst:) name:@"people.name" object:nil];
上面的
notificationFirst
就是一个类自己实现的回调方法:1 2 3
- (void)notificationFirst:(NSNotification *)notification { NSLog(@"people.name:%@", notification.object); // people.name:小王 }
在其他地方发送通知,则这个类则会收到相应:
1
[[NSNotificationCenter defaultCenter] postNotificationName:@"people.name" object:@"小王"];
KVC && KVO
什么是 KVC?
KVC:Key-Value Coding,即键值编码。
它是一种不通过存取方法,而通过属性名称字符串间接访问属性的机制。
取值和赋值实现了下面的两个函数:
1 2
-(void)setValue:(nullable id)value forKey:(NSString *)key; -(nullable id)valueForKey:(NSString *)key;
除此之外,KVC 也提供了传入路径进行访问的方法:
1 2
-(nullable id)valueForKeyPath:(NSString *)keyPath; -(void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
比如传入
student.name
,就表示 student 属性里的 name 属性
什么是 KVO?
- Key-Value Obersver,即键值观察。它是观察者模式的一种衍生。
- 基本思想是,对目标对象的某属性添加观察,当该属性发生变化时,会自动的通知观察者。这里所谓的通知是触发观察者对象实现的 KVO 的接口方法。
下面讲一个 KVO 的例子:
首先给目标对象的属性添加观察,下面是这个方法的原型:
1
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
其中,
NSKeyValueObservingOptions
是一个枚举常量:1 2 3 4 5
NSKeyValueObservingOptions: NSKeyValueObservingOptionNew // 提供更改前的值 NSKeyValueObservingOptionOld // 提供更改后的值 NSKeyValueObservingOptionInitial // 观察最初的值(在注册观察服务时会调用一次触发方法) NSKeyValueObservingOptionPrior // 分别在值修改前后触发方法(即一次修改有两次触发)
实现下面方法来接收通知,需要注意各个参数的含义:
1
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
最后要移除观察者:
1
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context