delegate
delegate 是代理模式的一种实现,就是委托他人帮自己做事。<事件一般通过protocol约定>
一般的使用场景是 控制器的反向传值 或 传递一个事件, A类(委托方)触发某些方法,需要由B 类(代理方)做出响应或处理。这种设计 耦合更低,扩展性更好(如tableView 的代理可以是任意实现代理方法的对象 ,已应对更对变更)
block
block就是一个代码块,但是它的神奇之处在于在内联(inline)执行的时候(这和C++很像)还可以传递参数。同时block本身也可以被作为参数在方法和函数间传递,这就给予了block无限的可能。在一段请求连续代码中可以看到调用参数(如发送请求)和响应结果。采用block技术能够抽象出很多共用函数,使代码高聚合,可读性,可维护性高(如网络库AFNetwork,GCD 中 ,链式编程中)。
对于反向传值 block写法更简练,不需要写protocol
使用block需要注意防止循环引用, 解决方案是用weakself。
block 类型属性使用copy 修饰。
block在堆中 ,想改变block里面变量的值, 需要加参数__block
Notification
一个消息通知机制,类似广播。观察者只需向消息中心注册感兴趣的东西,当有地方发出这个消息的时候,通知中心会发送给注册这个消息的对象。通知是一种在程序中可以获得高效协作同时保持较高内聚性的机制。他减少了程序中对象相互之间的强依耐性(这种依赖性会大大降低程序中代码的可复用性)。苹果给我们封装了这个NSNotificationCenter,让我们可以很方便的进行通知的注册和移除。
使用要注意addObserver后,必须要有remove操作(不移除可能会有野指针问题)。
KVO
观察者模式的一种实现, 一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。这是一个对象与另外一 个对象保持同步的一种方法,用key paths来观察属性,能够提供观察的属性的最新值以及先前值;
使用步骤为
1.注册,指定被观察者的属性, 2. 实现回调方法 , 3. 移除观察(不移除会崩溃),
使用场景
1. delegate or block
如果对象有超过一个以上的不同事件源,需要使用delegate, 使用规范的命名区分不同事件的回调,代码很清晰,易于调试;
相反如果对每个事件注册相应的block 显然不合理,如果创建一个可以接受任何可能输入值得block,即不简单,也不易读。delegate是“一对一”的关系,一个对象只能设置一个代理delegate,例如 CLLocationManager 定位成功后会通过delegate 通知一个对象(必须只有一个),所以如果需要更多对象响应定位成功事件,我们最好创建其他的locationManager。如果CLLocationManager是个单例,那就只能悲剧的切换delegate 对象(或自己实现广播机制),单例的设计本来就是共享的资源,和“一对一”的逻辑矛盾。
再看 UIAccelerometer的实现,早期版本中 accelerometer 单例对象有一个delegate,导致使用中必须偶尔切换一下;后来版本改成的 block实现 ,任何对象都可以访问这个block儿不需要阻止其他的对象来接收更新,block可以在创建事件的时候区分开来。所以单例对象就不能用代理。一般的delegate方法都(大多数dataSource )有返回值 , 像是委托在询问某些state(可能是对象的值,也可能是对象本身);而一个block 可以合理的包含 state(block真正是对象的一个属性),如果对象的请求带有附加信息,更应该使用delegate。
在苹果的API中 block 一般封装成 hander Completion 回调执行结果,所以block更面向结果,比如对于一个事件,只想知道成功或者失败,并不需要知道进行了多少或者额外的一些信息就可以选择block回调;
delegate更注重过程信息的传输:如发起一个网络请求,是否此时请求已经开始、是否收到了数据、数据是否已经接受完成、数据接收失败等。
delegate 面向过程的 可以在所有事件中维持 state 而多个独立的block不能
2.notifation or KVO
-
使用 通知的类之间 联系松散 ,发送方不需要知道谁去注册通知,接收方也不用知道谁发的通知, 这在一定程度上也破坏了封装性,但是有些场合就是由这种需求,比如 网络状态的变化, application 的生命周期状态都设计成通知让其他类去注册。
使用KVO 的 类之间 联系紧密, 因为观察者要明确指定被观察者的属性,他们就像绑到一起一样,共同变化, 例如购物车中总价 要和商品数量一同变化 。
通知 关注** 事件 ** 例如 application 从后台到前台的事件 就设计成通知
KVO 关注 属性(值) 如 检测股票价格的变化展示在view上
部分摘至 stablekernel.com